Official contract

Don't trust — verify

Verify Every Draw

There are no files to trust. Every draw writes its holder list, its commitment, and its payout to Solana as memos from one wallet, and the random number comes from ORAO VRF. Anyone can rebuild the result from the chain.

The addresses involved

Three memos per round

PB1C

The holder list, split into chunks of about 700 bytes.

PB1C|round|chunk|chunks|wallet:balance,wallet:balance,…

PB1R

The root. Seals the list hash and the ticket rule before randomness is requested.

PB1R|round|listHash|tickets|mint|ticketSize|maxTickets

PB1P

The payout, sent in the same transaction as the prize transfer.

PB1P|round|winner|ticket|amount|randomness|rewardMint

How to verify a draw

  1. 01Collect every PB1C memo for the round from the draw wallet, in chunk order, and join the wallet:balance entries.
  2. 02SHA-256 of "powerball-holders-v1" followed by each wallet (32 bytes) and balance (u64, little-endian) must equal listHash in PB1R.
  3. 03Sort holders by wallet bytes. Each gets min(balance ÷ ticketSize, maxTickets) tickets, laid out as back-to-back ranges starting at 0.
  4. 04Seed = SHA-256 of "powerball-vrf-v1" (or "powerball-daily-vrf-v1"), listHash, round (u64 LE), tickets (u32 LE), and the mint. The ORAO account is the PDA of ["orao-vrf-randomness-request", seed].
  5. 05Winning ticket = first 8 bytes of the ORAO randomness, read as a little-endian u64, mod tickets. The wallet whose range covers it must be the PB1P winner.

The Winners page runs these checks for every round it can read. With the worker repo you can also check a saved receipt yourself:

npm run verify -- snapshots/<mint>/<round>.json

Why this is fair

Committed before randomness

The list hash is inside the VRF seed. Changing a single holder after the fact changes the seed, and the randomness no longer matches.

Randomness nobody controls

ORAO VRF fulfils the request on-chain. The operator cannot pick or retry the number for the same seed.

Equal odds per ticket

Every ticket has 1 / (total tickets) chance. Holding more gives more tickets, up to 20 per wallet, so whales can't crowd out everyone else.

Same answer every time

Same memos, same hash, same modulo, same ranges. Anyone who reruns it gets the same winner.

On-chain payout

The prize transfer and the PB1P memo go out in one transaction, so a payout can't exist without its proof. Daily pot payouts are sent from the daily pot wallet. If the draw wallet itself holds the winning ticket, the prize stays where it is and only the memo is posted.

Open the winners list