Verify a draw
Every draw can be checked from public data alone. This page does it in your browser; the same check runs from the command line.
Five facts
- Entries are frozen on chain at the draw time, before the random number exists. From the draw time until the draw is made, sync can only cut a registration (for 4 minutes), never raise it, and voidMany can only mark one void. The entry list at that moment is fixed by the contract's Entered events, in registration order; each wallet owns a block of consecutive ticket numbers.
- The random number is a drand beacon fixed by the draw time. The draw at time T must use evmnet round
round = (T + 600 − 1727521075) / 3 + 1(integer division; genesis 1727521075, period 3 seconds; the round is published about 10 minutes after T). The contract checks the round's BLS signature against drand's public key, on chain. A wrong round or a forged signature reverts. The randomness israndomness = keccak256(abi.encode(uint256[2] signature))with the beacon's 64-byte signature split into two 32-byte words. - The winning number is public math. Pick p (0, 1, 2, … as picks are passed over) lands on ticket
ticket = uint256(keccak256(abi.encode(randomness, p))) mod totalTicketsand the holder is the first wallet, in registration order, whose running ticket total exceeds that number. A pick on a wallet that holds fewer tokens than it registered is passed over and the pick moves on: the wallet is not removed, so the ticket count stays the same for every pick. A pick on a voided registration, on a wallet that won within 24 hours, or in the big draw on a wallet that has won a big draw before, is skipped. In the big draw a pick on a wallet with t registered tickets of which h were registered, and not reduced, since the checkpoint (12 hours before the draw) is kept only ifh ≥ t, or uint256(keccak256(abi.encode(randomness, p, 43200))) mod 2t < t + hAfter 25 picks with nobody paid, the prize rolls over. - The payout is in the draw transaction. The Drawn event logs the draw time, the round, the randomness, the winner, the amounts, the winning ticket, the ticket count and the number of picks passed over, in the same transaction that transfers the prize.
- The draw's rules do not change. No owner and no withdrawal. The dev wallet can lower the creator tax and can announce a new draw interval or big/small split 4 hours ahead (or lock them for good), but it cannot touch the pots or anyone's tickets, and the rules above stay as they are. The dev's listed wallets are excluded from winning and cannot be un-excluded. The bot has no privileges: anyone can submit the same signature.
Check a draw
Reading the draws from the chain…
The draw, as the contract logged it
1. The entries frozen at the draw time
The hash is keccak256 of the snapshot JSON below (no whitespace, keys in order). Two people who rebuild the same draw get the same hash.
| Slot | Wallet | Tickets | Numbers | Held |
|---|
2. The random number
Could not fetch the beacon from this page (). Open the round with the link above, copy the signature field (128 hex characters) and paste it here, or run the command line check below.
3. The replay
From the command line
The same check runs outside the browser, with Node 18 or newer. Download verify-draw.mjs, chain.js and verify.js into one folder, run npm install ethers@6.13.4 there, then run this. It fetches the beacon itself and prints the entries, the hash, the signature, every pick and the verdict:
Exit code 0 means the draw verifies, 1 that it does not, 2 an error. Add --json for the verdict as JSON, or --signature <hex> to skip the drand fetch. Use another RPC with --rpc to cross-check the one this page reads.
What the check covers
- On this page: the entries are rebuilt from the contract's own events, the signature is hashed to the randomness, and the picks are replayed with the contract's rules. Any difference from the logged result is reported.
- On chain, when the draw was made: the contract verified the signature against drand's public key for the one round the draw time fixes. A draw with a wrong round or a made-up signature cannot be logged.
- One thing the logs cannot show: a pick can also be passed over because a transfer to that wallet was refused (the stock's blocklist or pause; if the prize was only the token bonus, the token). If the replay would pay a wallet the contract passed over, the verdict says OK with that assumption spelled out, and a trace of the draw's transaction shows the refused transfer.
- Not checked here: the size of the prize. The Drawn event logs it and the contract pays it in the same transaction, so compare it with the transfer in the draw's transaction. Nor can the logs show that both pots were really empty when a draw made no pick at all.
- The RPC: this page trusts the RPC in config.js to return the real logs. Run the command line check against a different RPC to cross-check.