Lifecycle & Draw
How a raffle goes from launch to paid-out winners. Every step after launch is permissionless: any wallet can advance the raffle, and no operator can alter or withhold a result.
Factory and child
The mother contract is a factory. Each launch deploys a separate immutable child raffle that owns its funded ETH pot, entry list, deadline, entry policy, distribution mode, draw state, and claim state. Children never share state; a bug or quirk in one round cannot reach another.
The four phases
| phase | what happens |
|---|---|
| Open | Sponsor has funded the pot. Eligible wallets enter once each (free; gas only) until the deadline block passes. |
| Armed | The deadline block has passed. No new entries. Anyone can call requestDraw() to register the round for a draw. |
| Drawing | A draw has been requested. Once the configured epoch delay elapses, anyone can call executeDraw() to select winners. |
| Claimable | Winners are set on-chain. Each winning wallet calls claim() to pull its prize. Prizes are never auto-pushed. |
Randomness & the lookahead
Winner selection draws from block.prevrandao rather than an external oracle, which keeps each child self-contained and cheap to run. To stop the seed from being chosen by whoever fires the draw, executeDraw() is locked until a minimum four-epoch lookahead past the request has elapsed — the seed depends on a chain of future proposers no single actor controls.
If execution stalls, requestDraw() can be re-called to reset the seed window, so a quiet or withheld block cannot freeze the round permanently. The randomness tradeoffs are the same shape as the Quintile Lottery's no-oracle draw.
Back to Raffle docs · next: Contract posture.