← Back to the pool

Provably fair

Every draw is settled by a keeper commit-reveal hash chain mixed with a future blockhash — no oracle, and no way for one party to choose the outcome. Here is that machinery, live. Full explanation →

01

Commit

The keeper hashes a secret chain and publishes only its head on-chain — before any draw exists. Every future word is locked to a preimage nobody has seen.

02

Pin a future block

Each draw fixes a seed block 5 blocks ahead. Nobody — keeper included — knows that block's hash yet, so nobody can pick the outcome.

03

Reveal & mix

Once the seed block is history the keeper reveals the next preimage; the word is keccak256(preimage, blockhash, requestId). Neither side controls it alone.

Adapter state

Status

Idle

Reveals remaining

863

Keeper bond

5 ETH

Recorded skips

0

Committed chain head0x9f2c7d…1122
Pending seed block— (no draw in flight)

Recent randomness

RequestSeed blockStatusWordLatency
#1241920005revealed0x7b4e…c1a942s
#1141916408revealed0x2f80…44de55s
#1041912810revealed0xd311…9f021m 1s
#941909212skipped65m 0s
#841905614revealed0x5a6c…07bb48s

Verify a word yourself

Once a request is revealed, its word is fully determined by three public values — reproduce it and confirm nothing was tampered with:

userSeed = keccak256(requestId, blockhash(seedBlock))
word     = keccak256(preimage, userSeed, requestId)

The preimage is the revealed value (its keccak256 equals the previous chain head); blockhash(seedBlock) is the pinned future block. Because the head was committed before the seed block existed, neither the keeper nor the sequencer could have known both in advance.