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

clientSeed: 0x93093f45d844b893dc3a4603e4baf9635a2bf92a9f54b0351ce01775321adaae

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xb24ad301eb1c7fa668a5eecdd428a3debbbdf890336228eabbc5c429699c7828

clientSeed: 0x292aa2bc5b5639455c31ba14352927d41047c62b345c73e384ca9d989f1dfec2

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

clientSeed: 0xf5a91c7954553c0913f88a76052ec33aacf55a0103aaa2d380057f66af06bded

serverSeed (revealed): 0xd1f520fb1ec9074747497308f5da723f116ea712e389fd7959a5e87ac7150db7

chainBlockhash (revealed): 8skVjwvvyn2b2uZdGzFAUM6YgHazmdPrRftbu6UVLquq

chainSlot: 458350739

Rapid Firecancelled

serverSeedHash: 0x6dd16fa331273c084530a3b8793910afda4586e997683a51ba839fcd1e8da2fb

clientSeed: 0xee70f44c5b50d8e0b47df311848b9269f8b5bdedcd706d9d77b602b47aa46cc9

serverSeed (revealed): 0x1ed5a5fdb9e22e2c8a67ea0f30a8b0f9be177cb4185782c767a1f8c19b90de48

chainBlockhash (revealed): F9HD4Lpn6w8BfiMgD12rHkYMYhQp99Q7Yjy4mMYj2YSB

chainSlot: 458349354

Rapid Firecancelled

serverSeedHash: 0x0f455dfcfb95dfc5808b446653c990ed6e4d54e175a7a53026179534900ebe40

clientSeed: 0x9f852efe9e997129dd481e2969becfaa6bdaddc91a50352476de25942b7087ae

serverSeed (revealed): 0x8ae38e3930f150a33255b4ba3657f9aa58c272cf5b6385146a5b3af1c75b0128

chainBlockhash (revealed): 8ZQ7ZUoHzL7SpwCCDVWZQ2HaaYxx3uAYBgUcFYukNAUW

chainSlot: 458347980

Rapid Firecancelled

serverSeedHash: 0x94cee74a30bb445e707f5ba4ac4c9557f6107217c8baf672fe09e4e1056c7700

clientSeed: 0xa8bed2159bb00cb53bcb15a10004e0488a276be2b602821bb1b6f8b8337de62a

serverSeed (revealed): 0x6b5127d2921f692a5421003e5be63c84b99c3b82b519ca7bfa032d66b4fc3c9a

chainBlockhash (revealed): EBF4W2PAjQHd8yUbojuedaoVSFduhq7m6aM95c33mzGV

chainSlot: 458346583

Rapid Firecancelled

serverSeedHash: 0xcd7dcf9226b84b1ba6d64f91022c582d317a0863c743b23e5fad643c03dcfb80

clientSeed: 0x12462f9df05a2a95479642474a18bb4348f95cf7a38f8f2890cf1fdb3648b216

serverSeed (revealed): 0xf36aaae4fab171f98d96a692584b44d5da6243a9b5906b8b59a1cceb05ab37e5

chainBlockhash (revealed): 32V45C5SkWofzsbMttQxHatBZv59LkJsuYTTtuxvLZyZ

chainSlot: 458345183

serverSeedHash: 0xcc8ca5a66c0ebd939e3a0aa5135d460f12091cbcb1c2c4768be17dd905adf4f1

clientSeed: 0xacce3c4da8c491b792948b4fc13c1049aceba584b377c8e351423dd9c039c4cd

serverSeed (revealed): 0xdb4e46e5c98177db42d58c802a7debb505728a14e83f3e62ea14029c398203e5

chainBlockhash (revealed): 3z6NHieLg6rAtmxD4oQrnPzrw9c6AQgyHTXpccz1TpiT

chainSlot: 458343808

Rapid Firecancelled

serverSeedHash: 0xddf6b3dc99d846cc1dbc399a779c68cb2ac3df382ac8f60e9aebdc376ce8c7c5

clientSeed: 0x86c06d1e2cd1753276592d0eb511b74bd5b56eb51661cbd652d62b6afe46a337

serverSeed (revealed): 0xf981bef5835be7c4fd5ab5a694fce05453951b7005378e5f7ff4b56c09f80863

chainBlockhash (revealed): HB6giLzgoMRFjj5fpNA4uFJNHhbNfy6R3x9PVcdDwdXb

chainSlot: 458343809

Rapid Firecancelled

serverSeedHash: 0xb4e49ad3f4f8880095cdcb726dea39d95dc8c28c42583afc9d2fc29ca26e6936

clientSeed: 0x9cede4e45e289df5075d5402c3b8ce918d472b44e1e3e2c5bd0e88756250317c

serverSeed (revealed): 0x231233338d2056c37aeb7887cc6fa5f979c34dd7554738d84ad2a252cf7963d6

chainBlockhash (revealed): 5bbZDrn2yeyymrUsBtt5LbCpNarYLHQa7yZk4dHmN4dw

chainSlot: 458342436

Rapid Firecancelled

serverSeedHash: 0xdd8d3cab03c1bf8d67c743f7876fcf5bca28b986da931005f52377e77bcb5cf9

clientSeed: 0x10f7b6280b3e58510c136357a1368354d61f8f70c1a7399ffb34e27b3a401826

serverSeed (revealed): 0x7c28df1b282087ee306a155967b87ef8af0de01729fb580225bbc1b650a31836

chainBlockhash (revealed): 5jVmW98JaXMbumYcMBb6uDQwqydMbMqT63LufmpJqTHZ

chainSlot: 458341058

Rapid Firecancelled

serverSeedHash: 0x1085495c64629c071f4af55e1994f45492529840448bff308cd7ea2e9bf3f3b7

clientSeed: 0x993f5194057d286d603400ef5c3b45d29e4ec60af091397d10c9ba7a9042c7b8

serverSeed (revealed): 0xefa2903053310528380d27f80ba3e054b9ccf3f2326b26ee5409698eed10877f

chainBlockhash (revealed): 3Lc8yeyz86dBFGVrVmeMMb11CbkewWbLQQVwwiktgGSA

chainSlot: 458339680

Rapid Firecancelled

serverSeedHash: 0xf85b71906a894dbab4514b0aaa2508c5d54a075be1896586cdc4848cae68b0d1

clientSeed: 0xf04c8900ae1b1e9f8a89ca602f99959562a4c1be91ddd8ecde446016907ad032

serverSeed (revealed): 0x7dc3ab25445e04dc1c68f9016270fc2e9265aec8ccc7c0494b880cbcdfa3da31

chainBlockhash (revealed): HErQDJ7pqnXbEhhTKygoDj6HwnmjKmubv24XNUeUK19j

chainSlot: 458338308

Rapid Firecancelled

serverSeedHash: 0xb706d106164f2de09a4f21b1ed4610684a33cc441e79760ca68815dd2fd545b3

clientSeed: 0x95b5b2ee096129fa185e9df219d6db2efd75f3e7367c6f23cde715b181d0a640

serverSeed (revealed): 0x911767fccf517823c429a5d4fe4c12604fbed7f690698324d5a34f2bef8b782d

chainBlockhash (revealed): 6QPEpuSBdVmt4bSUyazkGHi9ajLe9usPBMmzxsPKBhaq

chainSlot: 458336928

Verifier