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

clientSeed: 0x519db113edecbaa3d9960748641fc2c1168f2426bf1813d99d3f88b3dec65448

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): n/a

clientSeed: 0xc7232ae2d71047eab03ff5d11ac53807851945f1f3754091bbb5f13cee458411

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x7591ec4d1345de1f0409076449154a9bda730fe8cc1b78b0ab9c266ac98974c2

clientSeed: 0x2d4980a83e5d62b80ab5e9d3cb6fb7d6181e2d026ee0365f5e97164344ea655e

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0xd141a9cdbb4df966a65cb0c74863245d48c910c0b171cf2afd18e7f0c1bc3214

clientSeed: 0x5131b2aa68e920aacc3e9368129b70d342ce7bc6b0dab05039d62e1b63f33b81

chain entropy: not yet, arrives with the draw

Rapid Firecancelled

serverSeedHash: 0x66645ce0ff6ba0c1b80041351a774d0ed4a4aa82ac22f22f253cbd9de3446492

clientSeed: 0x2ed0a357ccf57ec5c6eef15d1265a808189d2a2948837d49c86f4a7fb09eee48

serverSeed (revealed): 0x93fab6007a9c52d906b5dc7d84aafd36a74747ee707013204993208de8913f23

chainBlockhash (revealed): 6pMjJaMJ6BDDEhfuBu17gtvJyN5HX91a7MXMjodgDra4

chainSlot: 458066074

Rapid Firecancelled

serverSeedHash: 0x5afceacb6d46f8aa97bcdea947cc719157d066132fd74f2446a69d2709787ec9

clientSeed: 0xfe2bf2089a17086ac6ad50d1a3f93fc7d61ced5c30388812cce50c7bec6a64a7

serverSeed (revealed): 0xaf1481a9e1694e4559f52db6a515586dba13e7e0a98ba68d9e304528ab44e4a7

chainBlockhash (revealed): 9HbvZhny8Uc5tGH3ZBE9aA5qX8FmvLmyPTCNyqdis9fs

chainSlot: 458064688

Rapid Firecancelled

serverSeedHash: 0x27ce4431811207134c7d9b76679ca86629ffe892a8fd704a280158eb8e8790b4

clientSeed: 0x54bbecbde976cb715dee3e1f58f7248d2b26c729aec54afe52fbe2d22c3bfc64

serverSeed (revealed): 0xc7b7ce74e8e635c8203c4bae1a592f9779b8519d35903facd537233c676286f4

chainBlockhash (revealed): BVsHnuGgAvxweXZWrrHYMfnyPGRjCEsgbcLZS2HNBZWV

chainSlot: 458063292

Rapid Firecancelled

serverSeedHash: 0xf4235e8270abfec2129a1f4abd3fd8f7a7d4099dcb0f3cb27d63947996152545

clientSeed: 0x55935cb34d9cdb412877e1b4137639fb67b0fedd4b3fd8755d64ea0e7fba4682

serverSeed (revealed): 0xfac81a4c818a4c98b2d585cc1e92667abed30d1f70ea7e448404f442fcc292f4

chainBlockhash (revealed): CBtJ7nZmWjUF16uNouqC77ezAuLUNctcDaecw2f1uuVT

chainSlot: 458061908

serverSeedHash: 0x6a5b1c1728b18df6331373ff0f1ae5cc15539e54c7b34b63db693233bce50f82

clientSeed: 0x69480c98d36b39149b7a83894de6650879c95387544365e1a512e1eaf9c6958c

serverSeed (revealed): 0x6630753d796c9cf7c901d6f5c3d92a5b40dd915608217679ea365552ac8e2f61

chainBlockhash (revealed): BZJREGyvb1Gn5nCgXFDhn5nrCJazX3aWASHrJGV1JP26

chainSlot: 458061909

Rapid Firecancelled

serverSeedHash: 0x1dd5ef3563691b357cb38462408e19e511bab277a7335e877889b6a3126258b7

clientSeed: 0x5a4743260a0da5a2a24254856705d9362432ea22b2e52514dcb5bd4d219ad9d7

serverSeed (revealed): 0xb933d39db4eca9e2266373eda9ff5c1ad7e6ac2391c52dc4f89be2875b62f200

chainBlockhash (revealed): HzXxHz57HHdZ4zBzptJhsaaQrPUkwBVBfLTAa7J9swyZ

chainSlot: 458060512

Rapid Firecancelled

serverSeedHash: 0xb874d029e45bac7ce7dfd096cf3de05bb98ef4bc461206fb753831584ac8981c

clientSeed: 0x5f899b1f623782b8b4e835be0575a723498ca7d83c8c66ebee3e573c4bd47bcc

serverSeed (revealed): 0x6cd5943d359182c9d856f0486e67b3eeaf5cc4ef33d558ee193dccf7b16452d1

chainBlockhash (revealed): 2BcJcvTZXBbLUdURkmo4t4ZdR9KJHT5hiYQ89SW1ynbq

chainSlot: 458059134

Rapid Firecancelled

serverSeedHash: 0xc16d2d7747da8037441ed135c776b6ee4bb3916da0e18451aa9d84878193ba4e

clientSeed: 0x02615b20de0617ec6ba1f8bc0fde60f51ff8392b0cb9969a266e18db791d32b8

serverSeed (revealed): 0x930ff69995782f5fe39d1fff9135712fd69e3ef31960c99efca4bfe65a8120b8

chainBlockhash (revealed): ECu8SrBcKUk4FVzH4Chz6TrjRxapQTcX9zZgKVcziTiT

chainSlot: 458057738

Rapid Firecancelled

serverSeedHash: 0xb36cc4df30e71a0452b56d56cc037799e8d221fcbf56e05913cb3e485912e6de

clientSeed: 0x9d801b90b09d37c475f037a66b4ef0e980bd3d8159cd16656b13c1987f44f63b

serverSeed (revealed): 0x26ea8bba9142a71246bd9ca6b9b0e09d8e420ae47bcc23d6353358800c3cd61f

chainBlockhash (revealed): Gg1kJgPGJ6E9ySGeCVDFdm3xsW9F2kBTkGFx2rULohs2

chainSlot: 458056353

Rapid Firecancelled

serverSeedHash: 0xc751f5e24799d9c6e2953c7ac82c0146b4046e64f0debc9f2faa75bfae8cfafd

clientSeed: 0xe885090629039af17f4c48edb1568c70562eaceb504f32797608ec624d65d282

serverSeed (revealed): 0xb38e4d289b9fe350673bf5405b4d6b86f074755846a7da4a9f9c9a98d941ca31

chainBlockhash (revealed): 56ZDwwhm6zGayUVhY1NdsvByhmJgHrsQTtByiotrux3B

chainSlot: 458054979

Rapid Firecancelled

serverSeedHash: 0x26b2d500b9ba44422ab9889755d2a20648f5aec0c27efca910c7b856aa77e0d5

clientSeed: 0x0be9f730ef7cbdc94c16337f5856961aaf522fc854c87a159e674a3f976336ae

serverSeed (revealed): 0xf95a71d0b5d7401dddbf0e8e35332230afea654ed6b5299d4a6ba0be596a1290

chainBlockhash (revealed): GTJjrJb6WweELEu53zQo64ZQR31fdSRDFHXLUZQnsntB

chainSlot: 458053603

Rapid Firecancelled

serverSeedHash: 0xc3e07be52384c6101a7135d3e88f4f3e7eb35aaabf582eab35cbb860be93855e

clientSeed: 0x9ce3f304e02017765121a1d9fc43af7a3daac5bed6c7f93c5b33f6d1134369cb

serverSeed (revealed): 0x44b951dcbdcb9a3a00fc6128c31d38eb4efaa63b2949dce30e5308bf09c70964

chainBlockhash (revealed): 7bidUG9uuzwMZvzjB5DDvMzkXE3L2iZcTGoESFW11ypS

chainSlot: 458052222

Verifier