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: 0xfacb150b06cc9245d9d878afe7ce86d4bcda8d29 — 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 serverSeed is 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: 0x33274b4aad855bad79099989ff8e2ca0fc666865 — 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.
Vault Run
A shared multiplayer round settled entirely by the VaultRunV6 contract on Arbitrum. Every bet carries an Auto target fixed when it is placed; one Chainlink VRF draw per round fixes the Crash point for the whole table. There is no manual collect, so nothing about the outcome depends on when you click or whether you stay on the page.
- 1The first bet opens the round and its betting windowA round opens on its first accepted bet; the contract records the betting cutoff and the result deadline on-chain. A bet that lands after the cutoff is rejected and never debited.
- 2One Chainlink VRF draw fixes the Crash pointAfter the cutoff the contract requests one random word 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.
- 3The Crash point is a public formula of that wordWith
h= the top 52 bits of the VRF word:crash = max(100, ⌊(10000 − edgeBps) · 2^52 / (100 · (2^52 − h))⌋), shown ascrash / 100×. Anyone can recompute it from the fulfilled word. - 4Tie rule: a target equal to the Crash point losesA bet wins if and only if its Auto target is strictly below the Crash point. A winning bet pays
stake × target, floored to the micro-USDC; every other bet loses its stake. - 5Stuck rounds refund — permissionlesslyIf no VRF result is accepted by the round's result deadline, anyone can call
markRoundRefundableand every stake in that round is returned. A late fulfillment never revives the round.
- Game house edge
- — (binds at round opening; a change applies to later rounds)
- Claim window
- — (after a round settles, the platform claims every winning payout to your casino balance inside this window; a payout still unclaimed when it closes is forfeited to the house)
What you can inspect
- Every finished round on the Vault Run table links its settlement transaction; the result receipt shows the Crash point and every winner.
- VRF proof: the VaultRunV6 contract 0x7d33c656aa52c6a7091c7211a706f4640a2c95c2 — each round's VRF request, fulfillment, accepted result, and settlement are on-chain.
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