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

clientSeed: 0x3f2f6b2ac33a8d47b452893ccdd75510bfac379e5fafe9af4af600282a398a2a

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x77909349b619d5221e34ee224fdcc3a939324a3112dcbe2a506f0d1c421f06bd

clientSeed: 0x44ede79281ca15f6af0bcb896e9a0f219664622850e59b323562f3af16e68a08

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xd141a9cdbb4df966a65cb0c74863245d48c910c0b171cf2afd18e7f0c1bc3214

clientSeed: 0x5131b2aa68e920aacc3e9368129b70d342ce7bc6b0dab05039d62e1b63f33b81

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x1de14308e3055e32d9036594b402fa7d4b23e064f19f926e2e66b8e23301aa1a

clientSeed: 0x19af35baedda7731037af3be6faf601530cecb36afc236f3791b09e792b82184

chain entropy: not yet, arrives with the draw

Rapid Firecancelled

serverSeedHash: 0x9395710efc3f8aecb2cc92c9ff4ebbf1290aecae7de3c8eba1dcd58eb688376a

clientSeed: 0x3e7fd7cb3286fecbbf2d425ad90b15a25afecb0eaf649751e788b066b28f5388

serverSeed (revealed): 0xcf40226e6e77d6a5b9da5ebd2e7ea65515ca2506d9b24ae74f45b0763a11f14d

chainBlockhash (revealed): FED71Z3JiWdkty1K5LHmZgkGzvp3tehTrNX4ZXTMW51V

chainSlot: 458152990

Rapid Firecancelled

serverSeedHash: 0x22d26ff6ce594fca2e90e36d5c6174e8cd890b9d95b81afaa113932d50d28cb4

clientSeed: 0x3cb2ac0fa7208df1c833f14669e1faf78880e1baf7a0e28dde171f00853e5c19

serverSeed (revealed): 0xbc68e1ecfd5443dbd91013462757aa3cb0705ed4e50d8651913aef474ad9a04b

chainBlockhash (revealed): 5ipDKfzkD1LxyGZxoz8mszqHFyXmyLAjxSiTaP8Ju8Kd

chainSlot: 458151611

Rapid Firecancelled

serverSeedHash: 0x4a0beb960a6570592000d3526d6dca106df7cb453720fee7767dd2803d7a1be3

clientSeed: 0x40a212403d165610be0aff039b85dbdb3218835b4f48a80b008d8950a2182385

serverSeed (revealed): 0x4904a1e9ba9b7c0eb55c091cb61b4e48d6e66f340c4c6f33ae717a61a974db3e

chainBlockhash (revealed): 8sYofow7ct1BJXCzd95fnqqmnwD9474PALLntyLtAYrr

chainSlot: 458150233

Rapid Firecancelled

serverSeedHash: 0xf9137315db213b486d5a6d93bbb054aa5d56b3d2286adaf29caf7b61eed71309

clientSeed: 0x07e592cae93cfd2aee253808af06bbac4ca526f84d49c1cf5c6f2901adffbffa

serverSeed (revealed): 0xf4bd2b3143341f2c25f87c0698e71da959ef8ece0b419ef0116e433e2786e83b

chainBlockhash (revealed): 7mPuScperrmRpjzqGqhy8ucn4W9CidbsDtMGyWEVvFS9

chainSlot: 458148846

Rapid Firecancelled

serverSeedHash: 0x231ae097e6f87ef4f67651f6dfe4563dce6b5e64afba379386348d030d68d4f8

clientSeed: 0x90382adc9b89ff9b108771d79540cd69ae755d4ef261d38e7ee0a01fd14d0de0

serverSeed (revealed): 0x062a547afb09d5fc9f66278dc2dbd4897248222430d3f42838be4849c322e1fb

chainBlockhash (revealed): EufNTtArmQXpGTEj8shbN9fkuKmYpKjucKCuivynkxw3

chainSlot: 458147472

Rapid Firecancelled

serverSeedHash: 0x005afe28a2008c0936e5d6707ae5f8b9a7a1698dddfdfb2589aebfba63fe2dd0

clientSeed: 0x26883c44acfaffb7bf520c7283e6c7446bffb04d7d6712fe52b087168d440533

serverSeed (revealed): 0x858c6619c77145cbff58ecdf6396c02bf0c731ed9f38ceceb56dda1c4786e1f1

chainBlockhash (revealed): 7PnKjKbsLrNbB7LZaBFrk3WPuDZ3Da6S9tVzkRRcE5hb

chainSlot: 458146104

serverSeedHash: 0x8f0154a381b3b9b8ea89dc13fcf53f673943902ee45a1ed855bcf3c324955ff6

clientSeed: 0x4e688347b416e2964575efa314980e93ebb6059e86cbfefc20be1de1e375562d

serverSeed (revealed): 0xf794d8d15bc96389813d62ade13d60f1dc44052930ac0b39419ad13595743b72

chainBlockhash (revealed): 3J13psYpNN1KRqwx7YyzkrdVcFdXrQkeEAFnNoXRESp6

chainSlot: 458144720

Rapid Firecancelled

serverSeedHash: 0xa18b61c9225f72f4817f41eeeb02b7b34b5bcb8037cb1e76f068c556fc9e3df6

clientSeed: 0xb94ec57c8da621905aa87a8fd3910750181f17a2bd479a099b52acf52bd7492b

serverSeed (revealed): 0x2f87da0a9429fe2dfc9444b4f6553a2dbc8e665c08e0b2e73784f769afda5676

chainBlockhash (revealed): 858wwmmr1ha6DfkCeFWkW55gDeFcofCobDEDtWzbRaDT

chainSlot: 458144721

Rapid Firecancelled

serverSeedHash: 0xbb8afc0e6815d46b6cf6b0a1a29c47985d3b1ea3cb04ddd59b8f6dbef5a3e29a

clientSeed: 0xc3e25a1a692807c9e009a1b4629637ab7f26845d86ab37ad79306ad3b67affe5

serverSeed (revealed): 0xae973e574dba1118cd7ee705c325c63e2e12670590967a9c4cab0369decc228c

chainBlockhash (revealed): 81vnh2djGgAB2qm1gBBXJtx3syA2PTVRjyJcon17bqSu

chainSlot: 458143350

Rapid Firecancelled

serverSeedHash: 0x880c774275bfde7d24e4f53fe2a5c83a78411127ab6e70dab7247c553ef058f8

clientSeed: 0x79e8273e7d429e9dfbbfd72c549be13ad5f7f5662c21a6923497e4f125afd9ca

serverSeed (revealed): 0xcf6452833807440dc0e74d0b1c7b54d449431db5d05a6c52899d2957ed1f6850

chainBlockhash (revealed): BL8ux3jcvm2pVeYzi4tD1eWG8rhx1oZhPoLyBtog3mR4

chainSlot: 458141964

Rapid Firecancelled

serverSeedHash: 0xa3755b22e58e2a93d8c3efa722d0558b8a02a434cb1a08d9e65a9a790940bb1c

clientSeed: 0xb9f0071bbdcc266c932b51bab14ec647904d0afddbe9ea90803103d048e52514

serverSeed (revealed): 0x63d1e8896f2f62662ace842f1fa0ab704bfade10c1f52a48e06dbeb9dfef75d8

chainBlockhash (revealed): fPAd41w2hXqefak4YhFtby1oz84WZFe1gFjGMhWCMtS

chainSlot: 458140594

Rapid Firecancelled

serverSeedHash: 0x8da16164ae393abd80dd439fb9276d236aff33c3b878709678ea0488fafa62c5

clientSeed: 0xe9b8cb7418eb64fb6bd126cd7ce395576bddf6ba12612aa2f82f95ecaef92ba3

serverSeed (revealed): 0x7f9be221a4c91beb8dca652719e5e488f6e3741c729ca8ff231d10546fe280a3

chainBlockhash (revealed): BR11jcKpzLrryewQHm9PcB5MJtCvGtmqBRRsDpqNqBBV

chainSlot: 458139214

Verifier