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

clientSeed: 0x565cb52e44752ac31f64efd57d5c099e81424437f882cd47628a6bf41e03e3da

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x4f6ae9257ee28bdebe8e5884137f88f4195f4a8871f9b5e787aeb5cb6e3d4061

clientSeed: 0x1926232e8e02b348a19b5d41f0c6e0ba4b672aaf7e30d67fb0b9ca5d56b0b380

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): n/a

clientSeed: 0xc7232ae2d71047eab03ff5d11ac53807851945f1f3754091bbb5f13cee458411

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xd141a9cdbb4df966a65cb0c74863245d48c910c0b171cf2afd18e7f0c1bc3214

clientSeed: 0x5131b2aa68e920aacc3e9368129b70d342ce7bc6b0dab05039d62e1b63f33b81

chain entropy: not yet, arrives with the draw

Rapid Firecancelled

serverSeedHash: 0x98c274a0b8d521e05099e25136e4dd09c6e40addf31dfc915fcff46b3a1acbad

clientSeed: 0xedec4add141e6b2fa6611188a78515c00ea20068bd0ea5b4bc34b17a369dce8e

serverSeed (revealed): 0x29654ecbb6b974e308a91bd01f6756a03839935dcf1c7e970d5ef26fb733a7aa

chainBlockhash (revealed): 3vgHyYE8PC3Bm9cq6V9L9oQTPtLmSd1HsXKyMSd2Ss5G

chainSlot: 457837568

Rapid Firecancelled

serverSeedHash: 0x4bc58380c9ab9645e54b4c853f1a303d415a2283e08c4a9ff8a3e4ab46d6a66e

clientSeed: 0xc63bc6a46934fd79c17f4a0b96b554807e2b144f28b948cd597b02053a2567f8

serverSeed (revealed): 0xf15e21b4d32a2dd9c951e7af077aae2b5cb4bebc9101ead10c8b67cc87dd0e81

chainBlockhash (revealed): Fq2wda6hWhAfP3bbbb8QvpHFVXn7SAE2BfpqKhSVJrUE

chainSlot: 457836180

Rapid Firecancelled

serverSeedHash: 0xf914ad2c796cd32b72593db1eb02cdc94d672cacc108c1e8586695bab681ea9b

clientSeed: 0xb106d2c5d2cde3edc122e2ab7a59ac474406df86064c83c54ea40c0bda289cf9

serverSeed (revealed): 0x17952b783242a92a837421763293fc3c91feb3b5636f483bddb3abdf9a2e1541

chainBlockhash (revealed): 9ddJC5NJMg8jqfEWtLXqnXw3LH2HLfMcUL4XoKZK3a8D

chainSlot: 457834796

Rapid Firecancelled

serverSeedHash: 0x4df093402cbb69a5ee8364e538f87083b2222fa369ec508b6908de0535fc368e

clientSeed: 0xcd412577bd2bc8fae78b69f60970f7679f50ec61f2647cab9107d66928a49185

serverSeed (revealed): 0xfbbb613e71fba8da8c5b54ad72acf0c65d29d678518d79d77437b6973ce817d1

chainBlockhash (revealed): 5MhntbczpWYpw3Xc98XUKg2H8MByGufAZNRf3YRE5Fgn

chainSlot: 457833394

Rapid Firecancelled

serverSeedHash: 0x519f9f3d77e2829295483f0de9bdf1e2f3a8d2735ba2f03196a5a3323fbd1227

clientSeed: 0xbe2e69cf9442dc6b120f3ff84428530496e250559afec3876dcf75bae4b2c0aa

serverSeed (revealed): 0xf2bd2789f9580f4a6fcf2002cb147362273e912d30a86b7ae6ff967f42eb60c4

chainBlockhash (revealed): 4okw6xAgLiWebzHUCUVRwkHp5DncWxvRqQsjNbBzj1Y5

chainSlot: 457832009

Rapid Firecancelled

serverSeedHash: 0x59bf4efe2de66cb153d1407ab92d6013ea87b3f779f247e9658b2ea067159764

clientSeed: 0x19595310eff0177bf6ab2e23c0b2cce07c56a7abd8d1f9f2b7801d155a91dacf

serverSeed (revealed): 0xe7c3613bc66220f2cd6e5601e8d05bf6037e143fba015f144ea642d3b1528a8e

chainBlockhash (revealed): G3RFxtvgH26EtHZqz72RkiugSxKXjuNUJqqTg29umGAB

chainSlot: 457830640

serverSeedHash: 0x36d24f8754a834f7c05ecff9efdb6655708b735dfebf080608c1ee0590d4b828

clientSeed: 0x42913d0f398e47b3bed5a0c835adbec683aab1faf2f2843872c54c8da89ba97a

serverSeed (revealed): 0x86b8ee6ee2b9d0d0a6ac0b7885ce63bfe0e9d2e358d5abb94f49123a8a10f556

chainBlockhash (revealed): CKmtuvPG1mrBX54HvqBLEZ9QVApQbaDXA9ms3VgvoA4c

chainSlot: 457829250

Rapid Firecancelled

serverSeedHash: 0x576bb0aba9d2ed03d6290e026735b918a690a98e6ca247d0f6bb13b2a9154caa

clientSeed: 0xadb38560677d1c8aa15d20957703dfe34619ae4a81778fa1df077c9a106f5187

serverSeed (revealed): 0x4d027d64eadebc7f415425e5ebcf6c630a12382780fc96b47304d8d17618e2fb

chainBlockhash (revealed): CKmtuvPG1mrBX54HvqBLEZ9QVApQbaDXA9ms3VgvoA4c

chainSlot: 457829250

Rapid Firecancelled

serverSeedHash: 0xb9c59f68dfad82583a31496ba7c0c60673b3ac63133d3e06eff5b8a84498e834

clientSeed: 0xc4ee839e97fb9f3362dd9979f8d7e6c9e3cfa7eb0a52387689fbf2102db0bdd2

serverSeed (revealed): 0xf64bcfa8d957417a82e57049828ee0baafe637c45d648d94c2e89fc4174d9368

chainBlockhash (revealed): 8zMkrYFMrgWocdhvVtbo2FtJWqHFB7A8xQBQWjtKaeqf

chainSlot: 457827851

Rapid Firecancelled

serverSeedHash: 0xf0aa1953d193fe56d989713c5125f72daf223da2d106813024a72931726e0ce9

clientSeed: 0xcbc2a7e04ecb77566db65a1fafdb7f4c62e916b4eee00fe0a29d598178788e42

serverSeed (revealed): 0x170669dd3a3cb4bd0265ddb66149b4100e852749a0f8c332707ad43921702f7f

chainBlockhash (revealed): GfqMc9a2CUPM9HqrXSRfTMMTYMP42coZZnLjccXwiNyv

chainSlot: 457826461

Rapid Firecancelled

serverSeedHash: 0xac6ff9a49a8d3f4792a50887bb596482facc49a33adfdf253e4663cee0d7f6c2

clientSeed: 0x7379bf4711195c891df7ff444d5679b4d031a6ec64a1597deb23d91f62d53d3a

serverSeed (revealed): 0x04c39dae1872f3b8e8f2f17e698050d7079272f1ab9a45f297a851956fbe6699

chainBlockhash (revealed): JYXmiLjeCLinbpveEke7MxfEC79kseW2QkaAvMeTmd1

chainSlot: 457825081

Rapid Firecancelled

serverSeedHash: 0x31677e8f63deaab294ee08eb47ef4a91fbeddfe12f27f9b8206d8679fa70125c

clientSeed: 0x6c125e2e31fb8a43df3ccc363552ceeb202af911a814e0f39fc55460178eb3bb

serverSeed (revealed): 0x8fcc61fbb774f751d290198753e706a49dbcfdbc47e66a93631e338430921a48

chainBlockhash (revealed): DARizkYccyhyDLDS7pe5gvcJMpFF1KzuFDtozTHisw6e

chainSlot: 457823679

Verifier