A Starknet Cairo contract for a lottery with an owner-driven draw and user-driven double-or-nothing spins. Integrates with Pragma VRF for secure randomness and ERC20 for fee handling.
- Owner-controlled draw: Picks a winner using VRF randomness and a ticket-weighted mechanism.
- User double-or-nothing: Each connected user may gamble their tickets once per draw window, doubling or losing them based on the parity of a VRF-provided random word.
- Concurrency-safe: Separate randomness storage for draws vs. per-user spins to prevent overlap.
- Wallet integration:
Tracks ticket balance (
u256), connection state, and spin state per user. - Fees handled via ERC20: Charges VRF provider fees via a token, using OpenZeppelin’s ERC20 dispatcher.
pragma_lib– Integration with a zero-knowledge VRF oracle (Pragma VRF). Used for requesting/receiving randomness securely.openzeppelin_token– ERC20 dispatcher interface for fee payments.
- Per-user randomness (
user_spin_random: Map<ContractAddress, felt252>): Prevents concurrency issues by storing each user’s randomness separately. - Single draw randomness (
draw_random_word: felt252): Held centrally and used only once during the owner’s draw process.
- Methods like
set_owner,add_tickets,draw,double_spinare restricted by appropriate asserts. - Each user may only spin once per draw window — tracked by
has_spinned. - Draws cannot be repeated once marked by
has_drawed.
- Ticket counts use
u256to prevent overflow during doubling. - Total tickets maintained consistently both per-user and globally.
- Owner calls
request_randomness_from_pragma(includes fee approval). - On callback, randomness is stored in either
draw_random_word(owner draw) oruser_spin_random(user spin). - Nonces are cleared after consumption to prevent reuse.
-
User Spin:
- User requests owner for randomness.
- User calls
double_spin. - Then checks parity of the random word:
- If even, doubles the tickets.
- If odd, burns the tickets.
- Updates user state and emits event.
-
Owner Draw:
- Owner requests randomness.
- Upon callback, calculates winner based on ticket weight.
- Owner can then call
drawto finalize the draw. - Emits
Drawnevent with winner details.
- Sepolia:
- Mainnet: