Provably Fair

Every game commits first, then rolls with entropy from the Solana chain. Here is exactly what that does and does not protect you from.

How a round actually runs

  1. Commit. When a lottery round, duel lobby or case battle is created, the server generates a secret serverSeed and publishes keccak256(serverSeed) straight away, next to the public clientSeed. For duels and battles this happens before an opponent even exists, so nobody can pick a seed that targets a known player list. Lottery rounds commit before a single ticket goes on sale.
  2. Close. Entries lock: lottery buys and sells stop at the closing tick, a duel needs both stakes in, a battle needs both players matched. Case battles also freeze a copy of the case's drop table at match, so later case edits cannot touch a battle already running.
  3. Entropy. Only after the inputs are locked does the settlement worker fetch one Solana blockhash and persist it together with its slot. Battles fetch theirs at match because the live per-round reveal starts there. The fetch only accepts a slot strictly newer than the chain tip recorded at commitment, so a game created and matched inside a single slot waits for the chain to move. A blockhash from after the commitment cannot be known at commitment time, which is what breaks seed grinding: the operator can try seeds all it wants, the final input has not happened yet.
  4. Derive and reveal. The outcome is one hash over serverSeed, clientSeed, the chain blockhash and the game id. At settlement everything is revealed: the seed, its published hash, the blockhash and its slot. You can re-run the math yourself in the verifier below and check the blockhash on any Solana explorer against the published slot.

What we can still do, stated plainly

  • The worker that fetches the blockhash is ours. It keeps trying until a value lands in a slot newer than the commitment, and exactly one fetched value is written with the settlement claim, so it cannot be quietly swapped afterwards. Attempts that fail or land too early simply retry, and a compromised or dishonest server could still time or retry that fetch. That is a single point of infrastructure trust, and no purely server-run scheme removes it.
  • Your account, your balance and the payouts live in our database. If the whole stack is compromised, fairness math will not save you. What this design removes is protocol-level steering: grinding seeds, re-rolling after seeing entries, or adding tickets once the draw entropy is known.
  • Rounds settled before this upgrade (visible in the reveal: no chain blockhash) used only the two seeds, and are still verifiable with the legacy formula.

Formulas

Winner-take-all lottery draws:

target(tier, attempt) = uint256(keccak256(serverSeed || clientSeed || [chainBlockhash] || drawId || tier || attempt)) mod totalTickets; winner(tier) = first entrant whose cumulative ticket count exceeds target; the single tier-1 winner takes the whole pot (legacy rounds paid up to 4 tiers; collisions with an earlier tier re-derive with attempt+1). Rounds settled after the chain-entropy upgrade include the 32 raw bytes of the revealed Solana blockhash (base58-decoded) between clientSeed and drawId; legacy rounds verified without it leave that segment out

Duel coin flip:

winnerSide = uint256(keccak256(serverSeed || clientSeed || [chainBlockhash] || lobbyId || 0x01 || 0x00)) mod 2; side 0 = lobby creator, side 1 = opponent (join order); rake = floor(pot * 0.5%). Duels settled after the chain-entropy upgrade include the 32 raw bytes of the revealed Solana blockhash (base58-decoded) between clientSeed and lobbyId; legacy duels verified without it leave that segment out

Case battle drops:

value(round, slot) = uint256(keccak256(serverSeed || clientSeed || [chainBlockhash] || battleId || round || slot)) mod 10000; drop = case dropItem whose cumulative weight range contains value; slot 0 = creator, slot 1 = joiner; winner = higher cumulative drop total; exact tie splits the pot after rake; winner takes the pot minus 5% rake, not the opened items. Battles settled after the chain-entropy upgrade include the 32 raw bytes of the revealed Solana blockhash (base58-decoded) between clientSeed and battleId, and derive against the drop table frozen on the battle at match; legacy battles verified without it leave that segment out and use the case's current drop table

Seed commitments

serverSeedHash (commitment): 0xc4c8ba0f21540359eb7c31c686110052c7b40cdf6a204e33442d5e8739d7e4e5

clientSeed: 0x29446f94bd40cfa2b18db877ee74a2cf9cd3cd735f9f40969db19c6d43510aee

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xba1b092c81ba77325fd6789197f21892d9849378949b0a0e05fd92d4f5d0ccdb

clientSeed: 0xfe76ee7a896d491976563aefe95d26d64644e29870884ee049e9c6480c6f721f

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xd449f4dc8f4994cc7c58d5ee3451cc40a65f0076a822926c1139ddd40bea0bb3

clientSeed: 0x784fc8db8aa524dc91467d096b5b9c554b245854bd8a025f940d258928a9b57f

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x1de14308e3055e32d9036594b402fa7d4b23e064f19f926e2e66b8e23301aa1a

clientSeed: 0x19af35baedda7731037af3be6faf601530cecb36afc236f3791b09e792b82184

chain entropy: not yet, arrives with the draw

Rapid Firecancelled

serverSeedHash: 0x3b79ffce384d927be0dd7787eb5ee0c0ab2bf77dc9cb7e5cbd62cef2c79e44de

clientSeed: 0xb55b717d666756960839d691bd037f4db5caa958ea04f952b272186e2f780943

serverSeed (revealed): 0xb5cd67453f0f282fc5bff4c260491139a5e22810db76a021e44a6cdd72d0298e

chainBlockhash (revealed): ARvLmPJHZvFwZPxKfeb7p2sLDDufF39iV1eh657T1fWT

chainSlot: 458249769

Rapid Firecancelled

serverSeedHash: 0xe3f1257e6e428d71fb6fd2a8f8cd9e5df67c90875c0fc9146cd4181238ba4f2e

clientSeed: 0x3133364dcfee7c2d1686a4ab095f6ff71a3c2a4261e30fefac164f1c3820886b

serverSeed (revealed): 0x69f2c6ffb0e7d679877392191e1b3fbb3bb29de2b3afd3798bd044e8cf9075f1

chainBlockhash (revealed): Eaznk3JDeM6pZrgfEPZpu87VL1EmSDna69Zef2rtgqge

chainSlot: 458248383

Rapid Firecancelled

serverSeedHash: 0x0501e8d287125e378ddf4d2e66777d3d5d05e852172cc04f68cf8d8104a6c346

clientSeed: 0x20b1b9df02b04691b7e356efa745af7f604dcaeb2e9ae17414fecff9634a0898

serverSeed (revealed): 0x6d37106580f062d63876a49ed9e73a06e9213aa6a646e3708a53cade326b4b0f

chainBlockhash (revealed): 35mXXJSLJYjP1tShNJv4uo4yFvEYyJ5Q5hziYAtXkTbH

chainSlot: 458246995

Rapid Firecancelled

serverSeedHash: 0xe01184290302345503b21b4c7f6c3ebc0ef0f3c8807d410fff109c272b552571

clientSeed: 0x109b9c364b611a8ad2cb2338a85b62d67c81d60da74fcfe3ecbb3e6f0d17ae2b

serverSeed (revealed): 0x7074f611c9007a9b25af6db439baf83cf02304abde9742eff63918a264a7a7e1

chainBlockhash (revealed): 6ik1zq6ypwvhFBR9uAm1t4qBvhbfD21p2Pcb2Z2a1oRq

chainSlot: 458245604

serverSeedHash: 0x68bebab09e1b615218f2b51eba0078656a138de7484e20649372a788a1419d48

clientSeed: 0x6691732c835aac7536760080311348078287ec3ac1d646b1454680223da705a2

serverSeed (revealed): 0x6f2222db5b98637516cfa14a812a37baf324ea43aab757b164328cff2a42404c

chainBlockhash (revealed): A1RxJTd6nfbrduAr3YSwHtSWYefcToLRYyebJpbLGmuB

chainSlot: 458244220

Rapid Firecancelled

serverSeedHash: 0x1a42a0d64a5d61356c3a13f062851803387b1df4d736ad91a248463e80b08cb2

clientSeed: 0xf2780ed9f500f822d4f7fc862fe00d26bae25605960a8efd8cc312f65a5d5a59

serverSeed (revealed): 0xf8e492915211455b2c0f9c2f19c896979be2aea177d504a8769d8daf1bc2534f

chainBlockhash (revealed): 9ebZ2KxHRRxuPk2yXfjZNJBe3GnTHaigkBCj2hdLciqj

chainSlot: 458244219

Rapid Firecancelled

serverSeedHash: 0xcc7faac2da069010a2e67485fe7fc5c2f2a132979e4f8ee851d7f5a64c495258

clientSeed: 0x069b358720084d2b8ecb0dab6ffcc6ea4b3dbbdc161ddf4206e56710612a7895

serverSeed (revealed): 0x63f0e1e2f431ebfed6420bbc89aa23a450fe58faa3303db0b1bb4c8f3319163f

chainBlockhash (revealed): HqMR25fKW1JzfiR5pSrdsgZjnvJxZxGdPbQjEqR4rYwF

chainSlot: 458242830

Rapid Firecancelled

serverSeedHash: 0x9254222b753536702786f634f4b3eb826a9848f95dfb8945afabb150751fa8e5

clientSeed: 0x5699929a094775f38e6ca65abf232bfde62dd18a58064b3c4215111d2974466e

serverSeed (revealed): 0xdf6e8c5fec884ed808cb9b3c33660f9441605bf918ed38d1d6e0aec1bd50b4c3

chainBlockhash (revealed): HEjhYQU73fYQ91EHoU5MJMeAwZ548H9VtQYnZeU3SUpL

chainSlot: 458241443

Rapid Firecancelled

serverSeedHash: 0xc843cbcbf3c88d5c14b5895e81dc948d363bdea909b89b1d14b01ce594f2ab0f

clientSeed: 0xe1027a9dcfb7e0bed79b21f6e35955b71870c5e3a5202051307c8ea2917e0a75

serverSeed (revealed): 0x7d59ce4f8ca3ec0bf5e95a0b17add070892d2a7758856ba4ed8e7cad320aa822

chainBlockhash (revealed): HvRDBib2rpgfM68sFhxZDodKcfLm9nxwpnM3jm51VAGT

chainSlot: 458240046

Rapid Firecancelled

serverSeedHash: 0xcb56c492fe95ec50e96a99690c6263451a635e96cff82c5fc29a372d0533b611

clientSeed: 0xc23ae8d1bf99046a41ed8138771418c188195e694d5e29bcc02f21867eafc01a

serverSeed (revealed): 0x066849718be2e938fbe3b9716a788b4c0917829558eaf061995ebcb70d705e87

chainBlockhash (revealed): 4cDpXkyNbZfhDcvHnmnyvPjkK8GMFNujp9CTDFfNCTzR

chainSlot: 458238662

Rapid Firecancelled

serverSeedHash: 0x77f08fd4bb9f0bc089da18a4a43760218f2abccd44cb05b01fa34114fdeab5a4

clientSeed: 0xa830929e47240de6ebb4f3a10544d3f0c850e449d2db3df7be6d199d2c5c5f3c

serverSeed (revealed): 0x24a223c5fd78c43e51cf8c0658453254d226ce1586f5ec0cef9680a8f13ea56c

chainBlockhash (revealed): GnHpxZr5dvUVm7edNN3n6vXSeoMeSasZRi32xv2Pc4oU

chainSlot: 458237264

Rapid Firecancelled

serverSeedHash: 0x395ad65c436466ba201a8cd0425195d1e3097be476c121496b4807e3e18c9c78

clientSeed: 0x15eb63c11ede3ea2021255fa34db1b6195b71446b16ced4fda78872549138e68

serverSeed (revealed): 0x1ebc4b848b52e301c613e7c9f9aa28e2af0e24dda16d9efd60f07f91df22ab68

chainBlockhash (revealed): 2sysifrpEZxkCZhSmekPSseKRuyuHn3vtwwmczyhtP9e

chainSlot: 458235858

Verifier