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): 0x83a1234b25f1b3e474537b383513edd680bd94667f8d23b8101d6d0ff6d53818

clientSeed: 0x102a8e737bfd73c0fd6eb95bfa4e9565890f35294962ca366298ebea7ddf51bc

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x8d37450f741e537247bf32f080963c605fcd6a4e0894e8cf169461b20040df6f

clientSeed: 0xcef1a1e492d6f3038f64aa20cc0d61f95caf55fa322172107833c57f8058a220

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: 0xf6fef46e584fed87aa0e55ba425e8945ffe1e21596c073b05221286be6afdcc6

clientSeed: 0x8681f19e8fd6856ef1313e58476815e1e3fc104f5791f1977ff5d61d5c31560c

serverSeed (revealed): 0xbcc5dd0354525a8f9711313f5d28c18c0c5e48b3651613785292b739efd60435

chainBlockhash (revealed): 5RLkxX9DJcq9HMRzMpbYRbwWVtvTHkyZ1Eu9QsQaWegK

chainSlot: 458413092

Rapid Firecancelled

serverSeedHash: 0xe7c2291fd0ed077592aecb07aacf64453bb61fa05c9fff11958e5a2a2ff583f3

clientSeed: 0x772ed3827f5264621a259f2211e4c342a499a8a8bf6f1a4e1d2366476ea177de

serverSeed (revealed): 0x434f7e60cf29d1b3da5154e744daa507a4b39957456b4d6570ce053c0a2097f8

chainBlockhash (revealed): G9vUvxcdVzzuLT6cTodo7hzLjSfJpCjs3J82Rk5BTydd

chainSlot: 458411701

Rapid Firecancelled

serverSeedHash: 0x99561a68ec653208fa1aa61082b76cb724cd15ebac90c42691dd73117c949fc2

clientSeed: 0x9673ef5f0b5281e8ed9556eb2dd479a84ccb4c4c03fadbee6ec5b578fa280e7c

serverSeed (revealed): 0x4775627d86a13bc2fad02da78194ffe6004f130a3db707623a3c9fadc47ecb71

chainBlockhash (revealed): 4Raui5y3aUKnrpwEuearKW9K56dm585fvJL6svDxvUT9

chainSlot: 458410309

serverSeedHash: 0xbbe0ca437af0c7f264245fd5679f4b73f455a4ea322388aac9ad4ad49825d5a4

clientSeed: 0x3a72ba9c4bb6f6b111c7fb0ead969e73c91ee30a2c3903a5d8a89de6c38becd2

serverSeed (revealed): 0xbd9c11d594290c26f3e73c2a53720ea1736997a1775cb1acb9e087a6826274d3

chainBlockhash (revealed): B4uEaXjVt8DQTKk2dF53z2iphxD1XBGAA8D1H3zBp2S5

chainSlot: 458410308

Rapid Firecancelled

serverSeedHash: 0xc2752ce9e8945006b4024f8c671fd8c02a5c6195629fecc984fd7e1f7ed06124

clientSeed: 0x8fca1318490c68b7b65ccdcb509825700eb30b655251b297900ac8c99eef1cc0

serverSeed (revealed): 0x405796fb6189b387230d3d504daea8eecd12accaf1c7ae242662c300e714307e

chainBlockhash (revealed): ELGDYoqk81V6QnjGfC2Q2wU5KYc71zZwPHRBjdVTC8RY

chainSlot: 458408933

Rapid Firecancelled

serverSeedHash: 0xad89f3d9dbc92af62a1480cda9f3a20e6b1fcf472e6326aab55999b62434de57

clientSeed: 0xb009a1771d9c957c41b7bdab4838a11facd1df6298134e9add9af377a3d513fd

serverSeed (revealed): 0x8973958b68bd7917cc46886c52a60688b17d9c06cad19b17e92ae97a20d547ee

chainBlockhash (revealed): 49WPEsEkELUhJtfe3aoc9kbLJYgD1GNKV1Fjpxg5rQmu

chainSlot: 458407545

Rapid Firecancelled

serverSeedHash: 0xdeba11b985b3b8925736beb3990aa6e2434d2107782e6fd099e0cf9069746303

clientSeed: 0xb49022d594ff6437c71b2ddcd944f1009fa3abe4922ca8e1cbb26db61e92d4f0

serverSeed (revealed): 0xf0d1f5cd4860bdf5f60cdcaf2c8e6362f335610756afb273e614cb87cc0cdfa5

chainBlockhash (revealed): 2CNsrbspik1Gi8pqoKHSyKH3oYU5qE7TULHbBVRMVBBu

chainSlot: 458406167

Rapid Firecancelled

serverSeedHash: 0x4068f2d56917e775448204f80f6f7775cc61be04b39c0df42c0259ca75c66173

clientSeed: 0xdce2f7a6e958db7a9b35f97cca2fe14b3736d7636d5c9b28fe61ac2ac930093b

serverSeed (revealed): 0xdab8a26794aba5e936545aa938bfa64d6622fe3c126ee126caa7030ba6e83c8f

chainBlockhash (revealed): 8kJ836pCGAUH3oaQRwLyUJnWoEPgBCnRtWQRiAhrN1GC

chainSlot: 458404772

Rapid Firecancelled

serverSeedHash: 0x8d73e5ed3b2db4eb284e108613cb6d02fc96434286ad0effbedacf5e5d3f8a76

clientSeed: 0x757e9288af2770f03dc48f967b9de1125fdf143cfaa5f70df9c129cda1d71ddb

serverSeed (revealed): 0xa024bc10d39e564b4b3d64af4deba7a33149b232869d6d1c60e7d66c96f8ecc1

chainBlockhash (revealed): 5F18Q396nM33rFTLrioKdVvNSpTuF5KGc5oAqTRUoVdb

chainSlot: 458403384

Rapid Firecancelled

serverSeedHash: 0x8eeff107ed890a1611bb9eff6db67e54d4ea3737d7ab07da97081e76cf7ba1e2

clientSeed: 0x22b73bad96627e53e223fe457d4bd5602ab5ab3adffd89c76ee71380035ab170

serverSeed (revealed): 0x493c4159ad04bc1faf74e50c57caa5849cec8be0ac6c93fc48e028bcce9d0914

chainBlockhash (revealed): BPhaH1YvhfpuCgUDmw7WVXgrPZrPwr5ukZ2XPk5HvHVU

chainSlot: 458402038

Rapid Firecancelled

serverSeedHash: 0x9140a54e0ad5927b5b441963cf5447624bb25d081a176090d625ef40b56d72a3

clientSeed: 0x4d1c133d394db2f53a952818242c7936194f79e5eeb9b92821793e5ecc7bb77f

serverSeed (revealed): 0x148c43f9de993efe4c17757d6fb760bce874b371af583df4f22b40c9faadcca7

chainBlockhash (revealed): Cs1phJ3uJ6GrNHtL5Vq36QhHmcqXTBgGrRcK8R8pFj8X

chainSlot: 458400649

Rapid Firecancelled

serverSeedHash: 0x0dbc413b0a1266953acbed54b4e91a37f090d59892e1004b57072bf555b0f545

clientSeed: 0xbb832562350f58a8784aa41014e06d4f9d9af0675c1e85de77c4ff069c097c8e

serverSeed (revealed): 0xac84eac3ca826886aaaaeb02f19c1bf3f9e594b5cab0229376d29ad509d172f7

chainBlockhash (revealed): DyyGZt9KVFnCyEWFG5Eq6hkvkMLNtp1UcM7ro98YSSeV

chainSlot: 458399267

Verifier