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

clientSeed: 0x8a70bb381859e971db37cd0b6cd121bf1d7e5759b38f3ea1dbc3a69f3f30ab5d

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xdb8ab84de713a55711b0d1dda64612630454c810336c18932af1d8f304ef430e

clientSeed: 0x114691595a123abeac69a29386cfe624fe34fe968d95da500f09f96e6131ca2c

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

clientSeed: 0x8d8c68b9cb0ebf924d6ca2a2454194d48f870cd1521a1722b54b1ad2288931ae

serverSeed (revealed): 0x531c166c95919117da3368d2e7357060370d7a9aa358cbfd4012ab39ad8d0743

chainBlockhash (revealed): HDML6WCbJRSSsPsVCzjFNv3M32XDJu13eANuZUBh472d

chainSlot: 458281558

Rapid Firecancelled

serverSeedHash: 0x5c10a4de3210f626918ad65a8a99b87c6d923d2938e8824a92e65e22006e1eed

clientSeed: 0xa6b1f801e89e8100cc332c1160e60468effaffab220abddf51b7b357b5811f17

serverSeed (revealed): 0xb9efe3d99275124ea465a33bf4aed8240f721b578f684606e2559455f93161c6

chainBlockhash (revealed): 4xdHDFCAR3Hu2Zdr6Bes9cCiJnNXcrNgHcWqjGoL2BYH

chainSlot: 458280177

Rapid Firecancelled

serverSeedHash: 0xa0172d4335c2e5acb93f8de69adc58fc98d54394458db423e4d4f81bf03eac10

clientSeed: 0x26351d356ad4727615001b44fbc802183c0cc9704e3a2f6e75eb9131834374b4

serverSeed (revealed): 0x288930d7ae29727db7107d0c508dcebe4ce2e4060ef568ce913078861de4bf8e

chainBlockhash (revealed): A9JY9ZLmUwEHqCeFjWFBQYTLgiYzwZ39JQ15mm1vWQ2v

chainSlot: 458278793

serverSeedHash: 0xc29743a92dede32eeadbdc417acad07c82afb9a64381864cc03f097deb3fce5a

clientSeed: 0x4b91cea767f18076de9f378896ab31e241ac0707bcd13f8cb9b71e6f2e9dfb2c

serverSeed (revealed): 0x32205dbe0433a6c2bdd77e5e08976b84fc65bafd599d154a9c61f1545a0a84dc

chainBlockhash (revealed): EPEmz9YRWDKmpGzMgRue8mrkgErcdbwgsUQq9Sh1qhPQ

chainSlot: 458277402

Rapid Firecancelled

serverSeedHash: 0xb071dde089b2c6fc795e392a194b8defe2ab5f9122c6422fb75265793455b6d7

clientSeed: 0x5e5970907d43a86770cda661e6749b92214f22e7de5115d075681e1771d5d477

serverSeed (revealed): 0x040704015037b8a9ccbb3edb19a530ca2dc9b25ddf0a8213e27891ba5f57ea9f

chainBlockhash (revealed): G96oJEkWz6QxYqn4RAQaPWWEQDaiKiSYDG6t2TjULT5X

chainSlot: 458277403

Rapid Firecancelled

serverSeedHash: 0x18a040cb6799a8fed7e12b88217e3783c2daf22eabaf95feb213345d52be74cb

clientSeed: 0x49f04e2ff89106662e59b08859dbcc7914e800e734515648a34eac1fa8c5d030

serverSeed (revealed): 0x10a655003e69f4b51fca1f3174a799bdba42beb230e5faf2d6e3417c8dfe5b4d

chainBlockhash (revealed): 3jafDkMU6q4dZH9iHoBSNznP3cFaytMABndXByD8bsZT

chainSlot: 458276014

Rapid Firecancelled

serverSeedHash: 0x61ab80eb6ec06ff202df6e8e45f921a07b0c8e486816d780a9407c609aabb39a

clientSeed: 0xec493f89c033904653512d8ce14ba0550ec6975a5d7fac2822e89ee485085703

serverSeed (revealed): 0x2cecbef319f41435a6a76e287246c1a0b10fe377d1f755e9a3f09d3f823f4355

chainBlockhash (revealed): HJMvRiWZ9BbWDgNaPkDi8F1U6LMAjn9AGQ48758Lzo8u

chainSlot: 458274642

Rapid Firecancelled

serverSeedHash: 0x7d279f7dcca13a64a8878ba2945c7868be5e29412e8bda868ea5bf6f7f325c88

clientSeed: 0xc32e68378b2ad03ddc9c8fc24feef2bcdd8bb79cf63035058d246f9eea5b8d9a

serverSeed (revealed): 0xbacc26d24a311137844f43f076d4c6824eedfb1b8ffdbdc58f8d745c72eee92d

chainBlockhash (revealed): AzizGofPLAfgLdTgSPzP8HEH5YbeC4SjnLMDkfugMQYm

chainSlot: 458273247

Rapid Firecancelled

serverSeedHash: 0x77d0410f4ad9fd272b58e0134386fd87b8613bedc2aa0e71259ce4119ce06ab9

clientSeed: 0x36889ba36d5f50b2188b2d1e09dffcc9549ca1f0a1dfce08670af0649790a204

serverSeed (revealed): 0x3ff1e25296caf15d187af7530ffd6dfe91e6fefbca1a752abc41b533e7557834

chainBlockhash (revealed): DR9E1mPiaZcdLf9S3KJBnwKHaWRHakP4nKjn3fsuCvi7

chainSlot: 458271870

Rapid Firecancelled

serverSeedHash: 0x6208f4020f43a3d4a5db6ab999728653c7d2e70653b98b6cc25ccb9743012cdb

clientSeed: 0x8d84c53fd3cc361c33f50ab35d224bb68961e1d45e7c6d0e3e91dc7b8e8a4357

serverSeed (revealed): 0x6628305470b113cf56664d717b7cfebe4c1ef2da1adb907109a916c419cb9345

chainBlockhash (revealed): HrmjD95Qi11G6betnbJodv7pmQgVGAENyXApV3whozjF

chainSlot: 458270508

Rapid Firecancelled

serverSeedHash: 0x79e5462560ac132958325521475594c45c56d143c3d6d4f0c887ef8f570d1255

clientSeed: 0x78594bc1407a4cf58b80096cad8561f6ea9fbe5cbc6c36fa2957a0ae0ba1b6f8

serverSeed (revealed): 0x4a326a6f4c340596186a82fd12a8d5e59723c60828fcb81e00a31a9a5263bb92

chainBlockhash (revealed): 929n3xJXFavV6ocpWHMPi2EpS7ykg6wZZHjhTGBDS7WC

chainSlot: 458269102

Rapid Firecancelled

serverSeedHash: 0xd75403f38b267f1537f1662a791e80b4389adf4ab7a1b2132aa9bfb403d00ea8

clientSeed: 0x3bfb30bdbc237c4cff401974dae350ab28e804044e42d266704227e489fb33a6

serverSeed (revealed): 0x504d91d1bd9ff2f3816773629dcb1fad901d3659a9022482fbc654afe893be5e

chainBlockhash (revealed): Frhp8j1EqWsMLho8y95unSz9Eq1hsnZQNDoZ9QvKTtpc

chainSlot: 458267712

Verifier