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

clientSeed: 0xcbc2a7e04ecb77566db65a1fafdb7f4c62e916b4eee00fe0a29d598178788e42

chain entropy: not yet, arrives with the draw

serverSeedHash (commitment): 0x36d24f8754a834f7c05ecff9efdb6655708b735dfebf080608c1ee0590d4b828

clientSeed: 0x42913d0f398e47b3bed5a0c835adbec683aab1faf2f2843872c54c8da89ba97a

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

Rapid Firecancelled

serverSeedHash: 0xece8669b92396927671a8021a6478b8f88d1dc7c4364ae9ab810a117c418ad2e

clientSeed: 0x2bc7bd8a82ac79aacb82355eee20dc36451ce5188c267aa8d08653f397f2d4a0

serverSeed (revealed): 0x2c27a6cdf36e204420269c9f002c4b912d0093ee1d46fffee4510d9133dc1e49

chainBlockhash (revealed): 885xNyDquCqmTQ4XgApWe4AzRqRYWTH5FupnU5Jfko2v

chainSlot: 457822286

Rapid Firecancelled

serverSeedHash: 0x1869faaa399e4ddee86696e33085d58b5c353d62021cc7013017d6487ab330d1

clientSeed: 0xbbfc82f09d39b3b00fc7b7e08da6df7f85e4a366a03baed22d341e898c72618e

serverSeed (revealed): 0x620d5b8ce994a11cad656e4abe868fd0cb7750d07ab04561c5944cfab0fb85f8

chainBlockhash (revealed): EainHEcT8DZCJMdejuGxTTiho4sSd4hvH6bc3XD1HogW

chainSlot: 457820895

Rapid Firecancelled

serverSeedHash: 0x09d16b1f5d874cc5a51e00201695cca2f2f60ef7fbcff54bbfc9003e1ea2c793

clientSeed: 0x8289ad3cf64ffe765b0186421c439aba42b42fece81e95a4fbd59c16c971b2bd

serverSeed (revealed): 0xc6a7e522e815d6821692fd7218706647032b7d912aae90e309d7f13368a883a4

chainBlockhash (revealed): EH96JNyUu6cemPqfESVj7Fe2ctbtriMBeg4QZNEBBQDK

chainSlot: 457819521

Rapid Firecancelled

serverSeedHash: 0x8d898d1d066ced2617ab2fe5305c92849f5b9b3fc4016582e14138cec8c158f3

clientSeed: 0xbe2aa37610a2289a4c5faec227525bc886ae410d71eaaeab0377c100805f1b7a

serverSeed (revealed): 0x7781b0f27337212b363d4275f82a5256e1a020e23a69410c7a575477602d4444

chainBlockhash (revealed): BfkXJcwqi4TsutMQBqHeJ2RShzKjXoricGn4mViSyrpv

chainSlot: 457818126

Rapid Firecancelled

serverSeedHash: 0x9609919daaf53cc67778bbd3c46fcbdc0a1d3d2f5736ed3752dec55fc5dfe62c

clientSeed: 0x2f9d59eab0a25b8836b6afc4c5e16b371c170d9458e760e8647b8e3945e7426a

serverSeed (revealed): 0x68a8be470c1d9899daea6af7bbecca15aa47666854eb25af8fd22e184d1e0745

chainBlockhash (revealed): 2BFqbtJ7TWifBXyFHPj5KwGxrKr1Hbt5TrbhV5H9R49J

chainSlot: 457816745

Rapid Firecancelled

serverSeedHash: 0x6165cda461eaa6952b96e45013f3ef336729e5402c6034fe26c5ed63d090cfde

clientSeed: 0x0dfed94613a473eec86ef0289b0385c1cffa357b954e5674dfd759aaf45aacfb

serverSeed (revealed): 0xbd96216c869b60fe698c2906b0ec47f8bd5115a1bcbaff7736fe2db945467583

chainBlockhash (revealed): FPK2fdeT2ASUWBR9b2Ge5xR4sZLZ3jFq4QWKLmsuWVhD

chainSlot: 457815362

Rapid Firecancelled

serverSeedHash: 0x095e90c7fc95fa6ecba8d47cb005cbf741014a1d3da01f0441ce345b6cc7aa78

clientSeed: 0x485096a7adc2754ec7a6376683052bcf15552592787cc3276472470d595633e4

serverSeed (revealed): 0xd23a7bea7c2a51d95e9a11af117730af48c3ba8a8227a02d7fda8dff4b5eba19

chainBlockhash (revealed): D1eeC2fGgQHUN7p5DhAJatTzUTUbhSCUwYbNjaTPNXrw

chainSlot: 457813969

serverSeedHash: 0x744bb78e13202940dd4f98f6fe06fee318308787ed41eca1f77c54abd4f91069

clientSeed: 0x0151d3bf0f8761060d40fcd0b198f13b1b0162160c0e71e06ba68f3c129ddd49

serverSeed (revealed): 0x8d3e48445a9d27cc1465332d16b3dbb1b32af3b90195860c73e4a7fea61bd26d

chainBlockhash (revealed): CCAUFTkDf6pCGEKoqXF9QmBHCE2LTBCprxJN8jNTpCTs

chainSlot: 457812595

Rapid Firecancelled

serverSeedHash: 0x5734da7531573169b365192f6bc60d52474a4a48fd06155ed1df0a021163dbaf

clientSeed: 0xb7b765c15e02c8b20138f23866b4a4ba4bc2db9e95038be6f14e8a2ea3c1f4c3

serverSeed (revealed): 0xef9161b459be791b0945b6fc0d43ba921a59550e61835700754896f30050f21e

chainBlockhash (revealed): AG9p5PvHnuDYCKFmXLpW9Yqk1s88GTw2BmoWFAysX6bE

chainSlot: 457812596

Rapid Firecancelled

serverSeedHash: 0xa8c70b0e619c9b3b296014040a9f62894956e39c31ffef7fb4eff0ab80fc3cfc

clientSeed: 0x80771b973b4f952bb83b8219076f614c5eba6bb74d8e486c92ce1adb1df9372a

serverSeed (revealed): 0xde24eacf3394ba04f7c34e62a4be87c7cd60b2248481a267f17685d3ba1c52ad

chainBlockhash (revealed): UMSjgWS5MpTPSACZUL7wFvEFXYmCi2znkH9G7X8x3q7

chainSlot: 457811214

Verifier