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

clientSeed: 0x9e47706a6dd0e4cf09cdfeabd972e8d63c7ef751ae4eccab5f408548b7032e2d

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xdf61a641fc1d01bd5d4d8bd7815150f14945c9fb58da1e5904af7233d482c81a

clientSeed: 0xf8359557dc837b392a111146aca620e0e1df44b98434af32163499d0522c0488

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

clientSeed: 0xe7c0ff57c3f011fb826a448a3964d2536ce1f743f330e6bb98e2ddfc2ab27221

serverSeed (revealed): 0x637ece44d4941a78950018d62cf86c1c168b8ed95a79206aec5c7fedbb62fa91

chainBlockhash (revealed): 9mbLS63vN4eXnpHseRFUJ1dhnsKn1J1Ki5UFzzLVVdN9

chainSlot: 458314815

Rapid Firecancelled

serverSeedHash: 0x6a8557a625a2b2abdda85038e1019e438f2169ef66bf472f809169357f66ca9d

clientSeed: 0xb59cf1ed8852fd6b250ae5210380e9ad4b579bae3505a0727fcc544b9ba65fb8

serverSeed (revealed): 0x6095b45017fba58ced409b7cb14912f30a23fb9929a6d6d75517d9bf5dabff93

chainBlockhash (revealed): H9cr7gZxXBFJLtuEGiT7HnM5fg9TbmqyvK88XVsnaNLj

chainSlot: 458313425

Rapid Firecancelled

serverSeedHash: 0x3ab39eb3b2a97ddc2a66c6e75efa34b7a0ba10fe96f8d794a4ed35df72815f5c

clientSeed: 0x55e91ce2c19ae12cbb4d92461ebe961d1da13460f732e6c55392669cc1c9b075

serverSeed (revealed): 0x455a0b3b2beec5d3f5e5fb8f1e2c07c9b09da0ebccd9d397889404c7147e7ca4

chainBlockhash (revealed): H1kgSfVxo6ExyzYR8wsiTMgQjn5dJhTHDbDJieoPPLbs

chainSlot: 458312037

serverSeedHash: 0x5455c06540e4ffdfb70610520c8b5b5a6b6f7628f0e2e4e71d8fbe5ad79e79c7

clientSeed: 0x7310047576962a6796d96e16079a581814c1932dba6c4999592069c5a81fb45d

serverSeed (revealed): 0x26d0fcde7b2fce41c8d151ebdff6de48bd984ff2b6c94e60aae7fef123756667

chainBlockhash (revealed): DZhzbWhHMGTkykVLADu8rUkaw74CgPaa8FZZ2593tLpt

chainSlot: 458310659

Rapid Firecancelled

serverSeedHash: 0x2aba3b9c7da16e1cc8c2e4d9f437ea4918798a56af97f43aa2971bc740266b53

clientSeed: 0x4f77ff369a27ba26b0801c57c273339d7f9f6a74c85fe622c364b4592c0afa8e

serverSeed (revealed): 0x9da3f0931d984a5a8ca229e89b63c8fbbb8be24fe170a4a9e39e1f1ca183a9b6

chainBlockhash (revealed): Bycewj21aWiqodUokSFsUjgEwn3R2WoJBn6pLHtjpxL9

chainSlot: 458310660

Rapid Firecancelled

serverSeedHash: 0xe477dbf827d0dbbc960cb9e858c24f2fa27131b1aeb8f25653b05cba006e7b02

clientSeed: 0xdbdf2b8945c5e4d5d8ab3c9d2ac343b5a949345550644ac5eb9aeb9408323079

serverSeed (revealed): 0x071119bd0519dac25b2cfd0a5381aca458b56f313154593b4fbd29dc87f3b976

chainBlockhash (revealed): 2oKJsGi98pjNNe9TywinnmSFQs1F2ESNkv5fMHBkwrai

chainSlot: 458309264

Rapid Firecancelled

serverSeedHash: 0x5bbcf36714f36bf69932cf324c7207e4207bc6aa96604a6e48b42f4a297022d1

clientSeed: 0xeb12cf0b38edbcd16ebd21fb161aa7833354f7fd3ceb1cfdbd96dbf511682f41

serverSeed (revealed): 0x91ca455448b4f85f47d52efb7e59bc23b38af5f90ba7ff6d527c7c3c6b4e0d31

chainBlockhash (revealed): 14X7AmiaRmQDnZA2LjCGyZXRaaGXkQMrrD27JZpcQcyU

chainSlot: 458307869

Rapid Firecancelled

serverSeedHash: 0x8f79a6c7ca0b6bc84f3b7abcd43b0a9b40ed81469c7125e5060b7f5a95874c86

clientSeed: 0xed5897b24bd4bd889c689f5ab59733197f67e5c2c76c99fd5c54765ad3f69857

serverSeed (revealed): 0xc2eef7013b83e57721d2cf9638af1eeaa9e183e8e5ebc3c48ba5ac0c90b96e53

chainBlockhash (revealed): 5vk8EKYPHeiE6eERNiQPz7ER1KkA8o5mxYEWLywacNQT

chainSlot: 458306485

Rapid Firecancelled

serverSeedHash: 0x81c709f82fb7a0c7cf981d593bd00eea8d193789c357b245316edb548eb36cb3

clientSeed: 0x0f4cca21323a1c39739ef2d308093c9c40ddc0634c332bd5e414d706e541e09e

serverSeed (revealed): 0x348b64684e96cda726bb502322b3c5c18261c21b2794edeb4ddd54baa462037e

chainBlockhash (revealed): 8rJvCWFSec6LWRshax9kxfsd5ZCbtaMshDYTKVFzrQcE

chainSlot: 458305110

Rapid Firecancelled

serverSeedHash: 0x70fbcffbccf3e8be3b99af7d1abffd4d3800b0b60a514a0c8d7a2bb89a08f450

clientSeed: 0x6082b498fa4bc830c06feed9b8698311a5b41fe99e6c61a94b69ed683ea13ff5

serverSeed (revealed): 0xbb168349ce9c4ce9dfd6c91127bcd6dab9235657dada4c4c508512e98d1a2687

chainBlockhash (revealed): BoK1U4tKA5vgd6BjEQBJ6HQU52DYq7oBUcTjZopziCWA

chainSlot: 458303740

Rapid Firecancelled

serverSeedHash: 0x118199482184ee9be74d50a0d94d6b7b7f3fc3b5958b7bf82d9d144b21e78756

clientSeed: 0x859ad71491b1e5a4659ba8aa50a01d6a3ff58d3857e39a3aa1f15e3959fffad6

serverSeed (revealed): 0xea3c9bda5bedcbd5d7e3457392dd07cb10bc34001e2cb3df94f81bf1f8e5dc90

chainBlockhash (revealed): BxqQs7ojEeeGGRVRzt1HpoL69MpgeGzaVTPHUEGjJRYb

chainSlot: 458302350

Rapid Firecancelled

serverSeedHash: 0x25b922a1715c350fde53e1af8c7d54762232fe707eeccd814db979f4308fd3ab

clientSeed: 0x7ba9ec6deee28ef3eaa2d208c445500d7582dc57e0b3892172778a93ab749c99

serverSeed (revealed): 0x0cacaab4efbab147b727f65075a890fe947670a41722680dcec394f711e5ab85

chainBlockhash (revealed): 3iPZt9U5bCvbFv5uZC4MpoKteQrFrfLSkZEhLfm5LYDs

chainSlot: 458300970

Verifier