Randomness Design
How winners are chosen and how you can verify it.
The draw is the heart of the raffle. This page explains the design goals, the source of randomness, how a random seed becomes a list of winners, and a worked example you can reproduce yourself.
Confirm the source before relying on this page
The randomness provider and the exact selection algorithm for each round are announced on OopsIWon.xyz and in the round's published draw transaction. The reference algorithm and example below show the method. Check that a round's published algorithm matches before you treat the example as a proof for that round.
Design goals
| Goal | What it means |
|---|---|
| Unpredictable | Nobody can know the result before the seed exists. |
| Unbiasable | Neither the team, validators nor entrants can steer the seed. |
| Committed first | The entry list is frozen before the seed is revealed. |
| Verifiable | Anyone can recompute winners from public data. |
| Equal | Every entry has the same chance, regardless of purchase time or wallet. |
Randomness source
Solana programs cannot safely use on-chain values such as slot or blockhash as randomness, because block producers can influence them. A raffle needs a dedicated randomness service whose output comes with a proof the program can check.
| Option | How it works | Trade-offs |
|---|---|---|
| Switchboard VRF / On-Demand randomness | Oracle produces randomness with a verifiable proof, using a TEE-backed commit-reveal flow on Solana. | Native to Solana, proof checked on-chain. Depends on the oracle network. |
| Pyth Entropy | Commit-reveal between the requester and a provider, then combined into a seed. | Simple model. Depends on provider honesty and liveness. |
| Other / multi-source | For example, combining several providers or a public beacon. | Stronger against a single failure, more moving parts. |
Source used by OopsIWon: to be published per round (the round announcement names the provider and links the randomness account).
The draw, step by step
Freeze the entry list
When the window closes, the program records the total number of entries N and the supply S. Entries are numbered 0 … N−1 in purchase order. No more entries can be added.
Request randomness
The program (or the keeper) requests a random seed after the list is frozen, so the seed cannot be chosen to favour known entries.
Receive and verify the seed
The randomness provider returns a 32-byte seed with a proof. The program verifies the proof on-chain and stores the seed in the raffle account.
Derive winners
Every entry gets a score derived from the seed. The S entries with the lowest scores win. Anyone can recompute this.
Reference selection algorithm
score(i) = SHA-256( seed || u64_little_endian(i) ) for i in 0 .. N-1
winners = the S entries with the smallest score(i) (compared as bytes)Properties:
- Order independent: each entry's score depends only on the seed and its index.
- Exactly
Swinners (or all entries, ifN ≤ S). - No wallet bias: a wallet with
kentries just holdskindependent indices. - Ties are astronomically unlikely with a 256-bit hash, and broken by the lower index.
Worked example
Ten entries, three NFTs. The seed here is an arbitrary fixed value for demonstration.
supply S = 3
entries N = 10
Alice bought 2 entries → indices 0, 1
Bob bought 3 entries → indices 2, 3, 4
Carol bought 5 entries → indices 5, 6, 7, 8, 9
seed = 00112233445566778899aabbccddeeff00112233445566778899aabbccddeeffFirst 8 bytes of SHA-256(seed || u64le(i)) for each index (hex):
Entry i | Owner | Score (first 8 bytes) | Rank |
|---|---|---|---|
| 0 | Alice | 3c4856d9370e3d86 | 3rd → wins |
| 1 | Alice | b5a7fbd3703b3e56 | 9th |
| 2 | Bob | 8cf284af4df16b3f | 5th |
| 3 | Bob | b036d36db54f3348 | 8th |
| 4 | Bob | 480f70eead843354 | 4th |
| 5 | Carol | 04141e87beca78d6 | 1st → wins |
| 6 | Carol | a3b3315d070a29e6 | 6th |
| 7 | Carol | a48f2c06765be9c1 | 7th |
| 8 | Carol | d209c6a76bbadbad | 10th |
| 9 | Carol | 28820453eb762125 | 2nd → wins |
Only the three lowest scores matter: entries ranked 1st to 3rd win.
Winning entries: 5, 9, 0.
| Wallet | Entries | Wins | Refunded entries |
|---|---|---|---|
| Alice | 2 | 1 (entry 0) | 1 |
| Bob | 3 | 0 | 3 |
| Carol | 5 | 2 (entries 5, 9) | 3 |
Verify it yourself
For a real round, replace seed, N and S with the on-chain values and compare your list with the published results.
Where to find the real values
N) and supply (S).See also Verify the Draw.