Provably fair, on-chain
Every supported game on luck.fun settles by contract on Arbitrum. This page explains the production mechanisms and shows the evidence you can inspect yourself — for the games that are live, and only for those.
Roulette
European single-zero roulette, one round at a time, settled entirely by the RouletteCoreV6 contract on Arbitrum. The winning number comes from Chainlink VRF — a verifiable randomness source that neither the house nor any player can predict or influence.
- 1Every round opens with a cutoff and a result deadlineWhen a round opens, the contract records its betting cutoff and its result deadline on-chain in the
RoundOpenedevent. Bets are only accepted before the cutoff; afterwards the round is closed to new wagers. - 2The winning number comes from Chainlink VRFWhen the round closes, the contract requests a random result from Chainlink VRF. The request and its fulfillment are public transactions, and the VRF proof is verified on-chain before the result is accepted. The operator does not draw, hold, or commit any secret that decides the outcome.
- 3Payouts are computed and paid by the contractSettlement follows European single-zero math enforced by the contract — 36× straight, 2× red/black, and the standard table payouts. The server cannot report a different result: the chain derives every payout from the VRF outcome itself.
- 4Stuck rounds refund — permissionlesslyIf no VRF result is accepted by the round's result deadline, anyone can call
markRoundRefundableand every stake in that round becomes reclaimable. A stalled or missing result can never trap your money: the refund path needs no approval from us.
What you can inspect
- The round's
RoundOpenedevent carries its cutoff and result deadline; the VRF request and fulfillment transactions are linked from the round on the explorer. - Settlement events show the VRF-derived result and the payout the contract computed — replayable against the standard European paytable by anyone.
- RouletteCoreV6 contract: 0x5727657F4226AB12A365ce6f16fEb178c5E84A40 — read any round, its deadline, and its result straight from the chain.
Slots
Every spin's result is math — not a decision. The server commits to a secret seed on-chain before you bet, your session fixes its own seed, and each spin is computed deterministically from both. The contract re-runs that exact math at settlement, so the operator can't fake a result. After settling, the secret seed is revealed on-chain and anyone can replay every spin and check it.
How a spin is decided
- 1Server commits to a seed (on-chain)When you open a session the server generates a random 32-byte
serverSeedand keeps it secret. Its hashserverSeedHash = keccak256(serverSeed)and the backend's short-lived signed offer go on-chain withopenSession(serverSeedHash, clientSeed, spinSigner, budget, validAfter, expiresAt, offerSignature). The hash is committed publicly and immutably — the server cannot swap the seed afterward without changing this hash. - 2Your session fixes a client seedThe same
openSessioncall records a 32-byteclientSeedon-chain. It is generated in your browser (Web Crypto API) and is fixed for the whole session— it mixes your entropy into every spin so the server's seed alone can't determine results. - 3Each spin is a signed receipt; the contract recomputes itFor every spin your session key signs an EIP-712
SpinReceipt(player, sessionId, nonce, betAmount). The result is computed fromkeccak256(serverSeed, clientSeed, nonce)— the first 20 bytes give the 5 reel stops (each 4-byte group mod 30), and reading 3 symbols down each reel gives the 5×3 grid. The paytable (20 paylines) is applied for the win. A monotonicnoncemakes every spin unique. The server shows you this immediately, but it is not the final word: the SlotsV6 contract re-runs this exact computation for every signed receipt at settlement. - 4Cash out: the seed is revealed on-chainWhen you cash out (Stop), the session settles: the operator submits the original
serverSeedtosettleSession. The contract checkskeccak256(serverSeed) == committed hash(a mismatch reverts — nothing moves), recomputes every receipt, and pays the verified total. The revealedserverSeedis public as thesettleSessiontransaction's input (settlement is finalized by theSlotSessionSettledevent), so you can re-run the math for any spin you took. Paste it into the verifier below.
What you need to save
Auditing only works if you have the evidence. While you play:
- •Server seed hash — committed on-chain when your session opens; read it straight off the
openSessiontransaction on the explorer. Copy it or screenshot when your session opens. - •The client seed — fixed for the session and recorded on-chain at
openSession. One value covers every spin. - •Each spin's nonce and the grid you saw — note or screenshot the 5×3 symbols and nonce.
- !Cash out to reveal the seed. The
serverSeedis published only atsettleSession, as that transaction's input. You can't verify without it.
Verifier
Paste the revealed serverSeed, the session's clientSeed, and a spin nonce. Runs in your browser — nothing is sent to us.
What's enforced on-chain
The seed is committed on Arbitrum. Your session's serverSeedHash and clientSeed are set on-chain at openSession. The transaction is public and immutable.
The contract recomputes every spin at settlement. At settleSession the SlotsV6 contract first verifies keccak256(serverSeed) == committed hash(the reveal can't be faked — a wrong seed reverts), then re-runs the reel + paytable math for every signed SpinReceipt itself and pays the verified total. The operator never asserts a number — the chain derives the payout. This is strictly stronger than an operator-reported net: there is no number for the operator to mis-state.
You can independently replay it. Once serverSeedis public in the settled session's settleSession transaction input, plug (serverSeed, clientSeed, nonce) into the verifier above for any spin — the grid it derives is exactly what the contract used. Any mismatch with what you were shown is provable evidence.
SlotsV6 contract: 0x771B637F5f7dd099790EE281D330ba3D8F166CCF — open it on the explorer to read your openSession and settleSession transactions and the SlotSessionSettled event.
Algorithm reference
Full logic, to the byte (matches SlotsV6Math.sol):
// Reel strip (same for all 5 reels). 30 stops. REEL = [0, 2, 1, 3, 0, 4, 2, 1, 5, 0, 3, 2, 6, 1, 4, 0, 3, 7, 1, 5, 2, 6, 0, 3, 8, 4, 2, 6, 5, 9] // Symbols: 0=L 1=10 2=J 3=Q 4=K 5=A // 6=Bell 7=Seven 8=Wild 9=Scatter // For each spin: // hash = keccak256(abi.encodePacked(serverSeed, clientSeed, nonce)) // bytes = the 32 bytes of that hash // For reel r in 0..4: // stop_r = uint32_big_endian(bytes[r*4 .. r*4+3]) mod 30 // visible column = [REEL[stop_r], REEL[(stop_r+1)%30], REEL[(stop_r+2)%30]] // Then apply the paytable over 20 paylines. WILD substitutes for everything except SCATTER. // See the full paytable in either direct game theme: /slots/ra or /slots/thunder.
Planned games
These games are planned for the luck.fun catalog as Coming soon. They are not live and there is no production fairness evidence for them yet — nothing on this page verifies a game you cannot play.
- Blackjack · Coming soon
- Baccarat · Coming soon
- Video Poker · Coming soon
- Plinko · Coming soon
- Vault Run · Coming soon