Smart Contract
Rust-based Solana programs handle ticket sales and winner selection. Open-source code ensures complete transparency and security.
Overview
Core Components
1. Raffle Creation and Management
#[account]
pub struct Raffle {
pub authority: Pubkey, // Raffle creator/admin
pub treasury: Pubkey, // Treasury PDA holding funds
pub metadata_uri: String, // Prize metadata
pub ticket_price: u64, // Price per ticket in lamports
pub current_tickets: u64, // Total tickets sold
pub min_tickets: u64, // Minimum required sales
pub max_tickets: Option<u64>, // Optional maximum tickets limit
pub current_entries: u64, // Number of purchase transactions
pub creation_time: i64, // Unix timestamp of creation
pub end_time: i64, // Unix timestamp of end
pub raffle_state: RaffleState, // Current state
pub winner_address: Option<Pubkey>, // Winner if drawn
pub winning_ticket: Option<u64>, // The winning ticket that was drafted
}
pub fn create_raffle(
ctx: Context<CreateRaffle>,
metadata_uri: String,
ticket_price: u64,
end_time: i64,
min_tickets: u64,
max_tickets: Option<u64>,
) -> Result<()> {
let current_time = Clock::get()?.unix_timestamp;
// Validate inputs
// URI format check - must start with one of the valid prefixes
require!(
VALID_URI_PREFIXES
.iter()
.any(|prefix| metadata_uri.starts_with(prefix)),
RaffleError::InvalidMetadataUri
);
require!(metadata_uri.len() <= 256, RaffleError::MetadataUriTooLong);
// Price checks
require!(
ticket_price >= MIN_TICKET_PRICE,
RaffleError::TicketPriceTooLow
);
require!(
ticket_price <= MAX_TICKET_PRICE,
RaffleError::TicketPriceTooHigh
);
// Ticket count checks
require!(min_tickets > 0, RaffleError::MinTicketsTooLow);
require!(
min_tickets <= MAX_MIN_TICKETS,
RaffleError::MinTicketsTooHigh
);
// Check that max tickets is greater than or equal to min tickets
if let Some(max_tickets) = max_tickets {
require!(max_tickets >= min_tickets, RaffleError::MaxTicketsTooLow);
}
// Time checks
require!(
end_time > current_time.checked_add(MIN_DURATION).unwrap(),
RaffleError::EndTimeTooClose
);
require!(
end_time <= current_time.checked_add(MAX_DURATION).unwrap(),
RaffleError::DurationTooLong
);
// Set inputs from transaction data
ctx.accounts.raffle.metadata_uri = metadata_uri;
ctx.accounts.raffle.ticket_price = ticket_price;
ctx.accounts.raffle.min_tickets = min_tickets;
ctx.accounts.raffle.end_time = end_time;
ctx.accounts.raffle.treasury = ctx.accounts.treasury.key();
ctx.accounts.treasury.bump = ctx.bumps.treasury;
ctx.accounts.treasury.raffle = ctx.accounts.raffle.key();
ctx.accounts.raffle.max_tickets = max_tickets;
// Set default values
ctx.accounts.raffle.current_tickets = 0;
ctx.accounts.raffle.current_entries = 0;
ctx.accounts.raffle.creation_time = current_time;
ctx.accounts.raffle.raffle_state = RaffleState::Open;
ctx.accounts.raffle.winner_address = None;
ctx.accounts.raffle.winning_ticket = None;
// Increment the raffle counter
ctx.accounts.config.raffle_counter = ctx
.accounts
.config
.raffle_counter
.checked_add(1)
.ok_or(RaffleError::Overflow)?;
// Emit the raffle created event
emit!(RaffleCreated {
raffle: ctx.accounts.raffle.key(),
metadata_uri: ctx.accounts.raffle.metadata_uri.clone(),
ticket_price,
min_tickets,
end_time,
creation_time: current_time,
});
Ok(())
}2. Ticket System
3. Treasury Management
Winner Selection System
1. Randomness Implementation
2. Winner Determination
Security Features
1. Input Validation
2. Access Control
3. Financial Security
4. Enhanced Randomness
Refund System
State Management
Raffle States
Event System
Error Handling System
Error Definitions
Last updated