Fairness
Every draw is committed on-chain before its randomness exists, and every result is recomputable from published data. Cheating would be publicly provable.
The draw protocol
- Freeze. The ticket snapshot for the draw is frozen: every eligible wallet and its exact ticket weight (fees paid, in wei), derived from chain history.
- Publish. The snapshot is published in full, and its hash is computed. Anyone can rebuild the same snapshot from chain data and check the hash.
- Commit. A commitment transaction is sent on-chain, binding the snapshot hash, the draw id, the algorithm version, and a future drand round at least 10 minutes ahead. At commit time, nobody on earth knows what that round's randomness will be.
- Reveal. drand publishes the round: BLS-signed randomness from the League of Entropy network, verifiable against the beacon's public key.
- Select. Winners are computed by a deterministic weighted-without-replacement algorithm over (snapshot, randomness). Same inputs, same winners, every time, on anyone's machine.
- Pay. Winners claim on the site; claimed prizes pay out in ETH. The full fairness bundle is published when the draw settles, before any claim.
The order is the point: the ticket set is fixed and publicly hashed before the randomness exists, and the randomness comes from a public beacon nobody here controls. There is no moment at which winners could be steered.
The commitment
The commitment is carried as calldata in a zero-value transaction from the published announcer address; the commitment id is the transaction hash. Its payload commits to everything that determines the outcome:
commitment = keccak256(
snapshot_hash // 32 raw bytes
|| u64le(drand_round)
|| u32le(len(algorithm_version))
|| algorithm_version // utf8
|| u64le(draw_id)
)
The bound drand round must be at least 600 seconds in the future at commit time. Randomness source: drand quicknet (League of Entropy mainnet; 3-second rounds; unchained BLS signatures), chain hash:
52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
Any round is independently fetchable and BLS-verifiable at
https://api.drand.sh/<chain-hash>/public/<round>.
Verify a draw yourself
Everything needed is in the draw bundle at /v1/draws/:id: snapshot URL and hash, commitment bytes and transaction, drand round and randomness, algorithm version, winners, and payout transactions. The verification is:
- Fetch the snapshot; hash it; compare with the published snapshot hash.
- Recompute the commitment from the bundle fields using the encoding above; fetch the commitment transaction from the chain and confirm the calldata matches.
- Confirm the commitment transaction landed before the bound drand round's time. That proves the ticket set was fixed pre-randomness.
- Fetch the drand round and verify its BLS signature against the quicknet public key.
- Run the winner-selection algorithm over (snapshot, randomness) and compare winners and amounts with the published result.
The repository ships this as a one-command check, pnpm verify-draw <drawId>, which performs exactly the steps above. But the point of the design is that you do not need our tooling: the encoding, the snapshot, and the beacon are all public, and any independent implementation must reach the same winners.
Claims never expire
A won prize stays claimable forever. There is no claim window, no sweep, and no forfeiture; claiming only accelerates the payment of money that is already yours. (The claim signature you sign on the site is fresh for 10 minutes as replay protection: if it expires you simply sign a new one. The prize itself never expires.)