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

clientSeed: 0x15aaa94cd680428e169e083c633462f0e7f69d8c64d59439070dea48614e5dae

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x0b24240dabfaa8e6a1528be49278dd260bbd838980e7144abad304041eb7b66f

clientSeed: 0xe084e0eb0d38c8a3b7357aa25a99aa5a90440da0e30b85e68657e67d3fe289dd

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

clientSeed: 0x824a9389c61433fe4ad65d918b908473051b69c9432ecd47c6d9a59791f6fec8

serverSeed (revealed): 0x4539dada513f67c079f07b75acebafe25ff88b262241b33a90860841a5e93618

chainBlockhash (revealed): YYrJ8nYNCb6DupzuqECEzGMKM66zaAVpx4e78DqHbLQ

chainSlot: 458220597

Rapid Firecancelled

serverSeedHash: 0x9b2988d4923d36c1ebc2aedb07a65423917070d330ac3ce4ae04a3f3bd96ae88

clientSeed: 0x6bcb5ccb87e8db155d1f6ca8e00b7c418db13356e860037cc8d35bead0d70c7f

serverSeed (revealed): 0x7a3b76b95ffa9aa9731b86e7fe82fa7ffb8546cb877eef485d9ec3be8084d10a

chainBlockhash (revealed): MjkNtd9cDfkRqWhSNwsmK1cPBsVyTKUPWNCRbZXLaM8

chainSlot: 458219219

Rapid Firecancelled

serverSeedHash: 0xb893642c324436f0b61b850b41c7053e176d217625dd40e5e0ed9addf31143d8

clientSeed: 0x4ce9d747ffa7994eae2a525bbe6df268a4607f8e645d4ee7b5cff34a166a56ab

serverSeed (revealed): 0x287d82834a148a6d8f2c0749fe1b00d5c6c5430547653993e9ac5a4133de3219

chainBlockhash (revealed): 2W8sgaqpNVcsqEfk7e2anuLfr5dPesHirZmhavxuKWjr

chainSlot: 458217847

Rapid Firecancelled

serverSeedHash: 0x4e70cfa5b0536006094edc37f7df4613842516f14a1222f6fa373466fed4f3e6

clientSeed: 0x8c9391331917800c9bcb18c1d991c9f96c763b558f236273bcbb049fa7500790

serverSeed (revealed): 0xb2032b972c29a883b9cd7959e21126d8294c45f2853b9eab21d50e3a06992c6c

chainBlockhash (revealed): HpwPfr7tMZkb3gHefSXY4Djj57NZm2tWCzmugjt6JoUn

chainSlot: 458216449

Rapid Firecancelled

serverSeedHash: 0x5379be2f2d80e4edff578e061456695d7340d70aab0032d1461f9eedd23b002e

clientSeed: 0xb65c004718c2372abb4c1d3b1531fbaf116a85b17fb51704bad440270b1a0be9

serverSeed (revealed): 0x0fb526fcaa141472bac646572df2b4c4ee13390aa41e27ead2d096d441830d6e

chainBlockhash (revealed): 9ScU5HBJWCTryDR9s4LbNpkNedHrVgvjobHYJ32rFJgz

chainSlot: 458215077

Rapid Firecancelled

serverSeedHash: 0x653326b9619d2a892d154ddb4416be2da4de03cd7d594366b1e6ac79501b5a6c

clientSeed: 0xd5d5baa2205481cf9325dc995be99ecc26d3dd984f1fca6c448d62d5aa722b21

serverSeed (revealed): 0x5af2926d391a075b3b5ec9a6f25f95835cde9a1f2e5a57f1d4248812924c395a

chainBlockhash (revealed): FYpSrYuUhbUjVCKSjXV9XDkEimax3nKL6gTLWSg71hK1

chainSlot: 458213690

Rapid Firecancelled

serverSeedHash: 0x54f194e1b1bb960e6bf94f73fe9d63d2def5490a413eb334eefe1205186982bc

clientSeed: 0xe6f8774822ca4acfe4b151c8fd49a11c827e70a4f787092c2b8c238b7adfc262

serverSeed (revealed): 0x77502c087d87d4ae2c95b4df654bdbdbd3820cc4981095fd088c2fe48ba60975

chainBlockhash (revealed): 6CTuxB2G4DhLgqeiphugt4xRpreYHdbQkkC6FYJQh98Z

chainSlot: 458212318

serverSeedHash: 0xa3fc3c9635fe014dda1c764bf5874d2b8f04eaf3670738f93ec24060de9892ea

clientSeed: 0x619e3f1aef6f45b63a5e20115bdae705066657725ce54619af0d1b54647239b9

serverSeed (revealed): 0x87e7c30a371fad03af7a111005c6afd118d84912374e5745dbd561523f2ed257

chainBlockhash (revealed): HeTUKSHHpEeMaEP8h26ZkSh2Xg5Q8epGUbiEvbnbeicA

chainSlot: 458210929

Rapid Firecancelled

serverSeedHash: 0xc9768b9ab9d324c3d24c0127a50b1983dbf352f1d00b4679b670256e1b4f983d

clientSeed: 0x4860f9ac012bbb15dbb6a6568c04568c4f9690548d34ee0a56f47bc094742192

serverSeed (revealed): 0x7ea7040d88f1652c64d8f0f983d0ef471a40feba49d407860f73149e4d853a90

chainBlockhash (revealed): D4aBzn4df4GXuL9ZQNMJH78jUVonkyFBa5hLCsCmWzDn

chainSlot: 458210928

Rapid Firecancelled

serverSeedHash: 0x82e9f822b17a63875b6beeaa26b2e260d0e7597b19e5355e3c7a2073e1eaf3f1

clientSeed: 0xdc1b50f4c6e1b41f8cb132954181ba003412e4e691eb96a4edd9d15a16aee6d4

serverSeed (revealed): 0xe4acdbf0617c1fc647e7627d19bfea0e4c0c53c047d9b11638b504e511e2faa2

chainBlockhash (revealed): 7Sk5vCeK2nuosx2VWGkwcmvmSGS6t7eaJEfVUeh3rQk8

chainSlot: 458209544

Rapid Firecancelled

serverSeedHash: 0x5ad450f021dc4a60349fd566112fe859696398ccddfdd054bdafeff2ac5f1479

clientSeed: 0xe934b1e1b5b0db75791254809d7e95142ad6cdc43ab26e0acae7a4e65eb30aca

serverSeed (revealed): 0xa12b8389bd7f788f5094d86c9fe2eb939d29884cdd81789ba41d25859a56d6fa

chainBlockhash (revealed): i4x3xoeJdPKdiSx1cqkrJisTX2GEH8zsHy6hLNTpEmz

chainSlot: 458208157

Rapid Firecancelled

serverSeedHash: 0x09ba067a1ba0e8bebeb2a3a10c947da5f2ab9a908c59585e5b8cc67e78b76bd8

clientSeed: 0xb183fbb1eaab3a7a4a681760c06e86c668e012c91263838596bb5433fc84589b

serverSeed (revealed): 0x1eae3a930a4cc1bd032927934b6c787ef9a3396810a35016f1ad82549fc1d9dc

chainBlockhash (revealed): DDttvBcdzM8CRBYCXpHJV8gEssM3pYtwT22vEPcMtXpD

chainSlot: 458206787

Verifier