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

clientSeed: 0xf397df5a67ee7f5c1cca65ab954ef659f10a6b8d3e6b6ece89ae6c1166e3f929

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xd141a9cdbb4df966a65cb0c74863245d48c910c0b171cf2afd18e7f0c1bc3214

clientSeed: 0x5131b2aa68e920aacc3e9368129b70d342ce7bc6b0dab05039d62e1b63f33b81

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x08c502c6b3284c36e6965436e475bfb77c52712c3954cc97c405354d179141ef

clientSeed: 0xc9c55467317979c3ea0ebe1939e501eb5331c9c7b7dd3339c7f3bcdf7cdcb5fd

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x1de14308e3055e32d9036594b402fa7d4b23e064f19f926e2e66b8e23301aa1a

clientSeed: 0x19af35baedda7731037af3be6faf601530cecb36afc236f3791b09e792b82184

chain entropy: not yet, arrives with the draw

Rapid Firecancelled

serverSeedHash: 0x64040ffa2933dd1d578ed6d25bff1019dd2a4324e0747880c8a72628e9cbc956

clientSeed: 0xa92aa6f7eba16f62f658dafc6609dd44b5ffcb4712fa315c325556d2e0e3d0e9

serverSeed (revealed): 0x7801c1afa4135877c0f508aa54168588072e22e30476fbad06eb48f7887935df

chainBlockhash (revealed): 3JC419AqQPa18pPraMxKHjGdD4LGYMu3zn1JgMtvuNZL

chainSlot: 458170942

Rapid Firecancelled

serverSeedHash: 0xa5b8f132cf5858722d1792403853fe9cd6b273f9811a4d5550812d4e2f27245d

clientSeed: 0x1fa3c5875643e42c0b827ac5351f9b6c82de97f8241d51bf4dad2d872c53c475

serverSeed (revealed): 0xe826528b1a158e6e5c904e1c3d65203767e087d4566e884ee049ca7399cd3974

chainBlockhash (revealed): B4aiTcMjozhPN8Fvx8ZK28W1XuMuJCk5ZCn2riGBBFfD

chainSlot: 458169552

Rapid Firecancelled

serverSeedHash: 0x914dfae3fb3be80f8d5fe4f2673dca087261a77167af39ffe0d9d2cafa7cc79d

clientSeed: 0x3200b8734697c4ad9d681b22b605cf8ec2178bd95fcef6bf9654fdbf41e1c420

serverSeed (revealed): 0x6677eff6d48b86c632137f96182597fc16306a71294cd216757081b04f68a6ff

chainBlockhash (revealed): 5NtPn8HKRJVcrHKr77ae6b5JbTvbbvKCAdxXCjPLA8f7

chainSlot: 458168180

Rapid Firecancelled

serverSeedHash: 0x296d264e2d4ddcd72a8e6aa50b0ec16a8e113105bb81001327265bd56f360aa2

clientSeed: 0x359ee115433ba789bb9a16a30bd7974d309b67adee9644da8daddcf108713df4

serverSeed (revealed): 0xd16adb53a73058b8be1bc57477e9a37da8bfd78f5cdc3e9a880e360cb1ff6f92

chainBlockhash (revealed): 2MU2UZmAe6SbSDH7BErruMjhnLtkrreqDGvMejiJbshh

chainSlot: 458166798

Rapid Firecancelled

serverSeedHash: 0x20f64fcb4acc5a4c5ae8200eccfd3eca285ba0fff55cd53c1cdd3e212b7c7935

clientSeed: 0x98f709a5e6795209930b866a43429ff12c919561c22acb55cd7cf1073c572ce9

serverSeed (revealed): 0xfcea3f81271c553bd339f19b36e5d8ba1b3dcfb0498156bab7646d772f6b9838

chainBlockhash (revealed): AWvNCuRes5Asj64uVRHu5fFsWFneuUcXukPfRo5DwUGg

chainSlot: 458165425

Rapid Firecancelled

serverSeedHash: 0x2a9f34caf4dd9543dbcdcc7e273f25795d7cef8a80be3f29a1b53e99d1f6dfa2

clientSeed: 0x681cf766729e8b1d46d6baba2d0ebe511761a905156ae641c0d2f62f084cc90e

serverSeed (revealed): 0x62cc771636d299770e4ff3a9423bdfa318fdb7036c50fc25eea92ea73f67f7d4

chainBlockhash (revealed): C2PD6zUkfqfFxLWe4QETMj6xsHif3SdhhufZyVzutYfg

chainSlot: 458164048

Rapid Firecancelled

serverSeedHash: 0xb60995e20d565f570dc892ca0362bb98e2b6cafcefb32548b50530a1a6629364

clientSeed: 0x6fefaa5240396de1fdde44fb01db59a980ab9c0e9028452e872854b9ecfbebc1

serverSeed (revealed): 0xba11032fb5dc5fa4db4093cbda6b9ea22bfcfd9ca7728a5caeba71ad1e98ec50

chainBlockhash (revealed): AMYd4Q7VTtUPAr9umPveWRiPBNSohC8zAbt8SsrY8fi1

chainSlot: 458162650

serverSeedHash: 0x77909349b619d5221e34ee224fdcc3a939324a3112dcbe2a506f0d1c421f06bd

clientSeed: 0x44ede79281ca15f6af0bcb896e9a0f219664622850e59b323562f3af16e68a08

serverSeed (revealed): 0x2a11236412bd166f142fd6901ccae5e5668c4f33de0e6c65af986209877675df

chainBlockhash (revealed): 6wsRGJ7cDrQ7yJCtr9PUcycAEKtZbxeACvKqQBmyAM1o

chainSlot: 458161278

Rapid Firecancelled

serverSeedHash: 0x512a020f0c88cbb9a06f87a8a8a6ad92ddab3c85abdbd6e07d4b4aed4273866a

clientSeed: 0xbbf84cde74af6a2e6467f1fd775b4dcc5615db82b4d11fad2bbe2115cce27547

serverSeed (revealed): 0x125eb6d01e420ea7f3fc4b4705c80e2ee1d6e68e45aa4844d1e0093d64e67489

chainBlockhash (revealed): 4CutHtNjqx2LjaHk7iJKDACQKZa3JMr2kHesg4rqDG8F

chainSlot: 458161281

Rapid Firecancelled

serverSeedHash: 0xff9cb7605415eebc60405bb429b1c3c2da8e48b762831eb4fc41597d38a85dc5

clientSeed: 0x90131540ed7059321964031ee1dee17f6315b171ebf72225969aacc97f1cd45b

serverSeed (revealed): 0xea0474cc4c6a5c114886518f33f4e463c4b66598e3957f79f87566a99c0510b0

chainBlockhash (revealed): BSLp1JfUVvCj1MRtDDkxyj48YHy96xziqeBQtVhbj1hb

chainSlot: 458159885

Rapid Firecancelled

serverSeedHash: 0xb1cc344c439ab4f06993bf4fc8f594a135afc5afd90a7ad8e1a2a2868b4c9b7e

clientSeed: 0x427e786c8b39a2057702053d1e3a936b41a74ed459d17cbeb0b2040b382d436c

serverSeed (revealed): 0x5cbddcfc5c8daf3a2f19e98de14aac7c221b9918a92d1b09a9bfae19a7199515

chainBlockhash (revealed): FTCrys81Xh9uwpy5P6qnU7MKE8XrhTzPa7DctxgBLcx8

chainSlot: 458158494

Rapid Firecancelled

serverSeedHash: 0x831afabf7bb7ba608ef4be949ef635175717714ad2387c9aac39292d395b1a7b

clientSeed: 0xdbde101b0a918e07136cb77adf3920a118dcfbc610a53b5daaba6afe3050325e

serverSeed (revealed): 0x2d2108f8e869e9ed17db7699f18a1507f6e1320f7b8d4c1904aa6be0fd648c89

chainBlockhash (revealed): 2XP1DZ9V1cZyNykyWatugvAsz7ZrVcRNxc5qsWqs9biS

chainSlot: 458157134

Verifier