originals
Dice Under the Hood: Roll Derivation, Payouts and Edge
How the crypto dice game works: deriving the 0.00-99.99 roll from an HMAC, the payout formula 99 divided by win chance, and why every slider position pays 99%.
Crypto dice is one number and one comparison. The game produces a roll between 0.00 and 99.99, you have already chosen a target and a direction, and you win if the roll falls on your side. The payout multiplier is (100 − edge) / winChance, which at the standard 1% edge is 99 / winChance. Everything the game does is contained in those two facts, and both of them are checkable.
How the roll is derived from the hash
The roll is not generated when you click. It is a deterministic function of three inputs you can see — the hashed server seed, your client seed, and the nonce — which is what makes it verifiable after the server seed is revealed. If those three terms are unfamiliar, start with how server seeds, client seeds and nonces fit together.
The standard derivation:
- Compute
HMAC-SHA256(serverSeed, "clientSeed:nonce:cursor"). The message format varies slightly between operators; the cursor exists so games needing many numbers can keep drawing. - Take the first four bytes of the digest as integers 0–255.
- Convert them to a fraction on
[0, 1)by treating them as base-256 digits:b0/256 + b1/256² + b2/256³ + b3/256⁴. - Multiply by 10,000, take the floor, divide by 100. You now have a roll on the 0.00–99.99 grid.
Here it is on a real digest, computed rather than illustrated:
import hmac, hashlib
server = "ee4e2c4a5f0d7a1b9c3e8f60b21d4a77e1c9038b6f5a4d2c7e0b1a93f8d6c5e4"
client, nonce = "my-client-seed", 1
h = hmac.new(server.encode(), f"{client}:{nonce}:0".encode(),
hashlib.sha256).hexdigest()
# 06b915afb26c75f7a525849c8dba060c10f2d8f197c1857b4f0edbc66bc7b46b
b = [int(h[i:i+2], 16) for i in range(0, 8, 2)] # [6, 185, 21, 175]
v = sum(x / 256 ** (i + 1) for i, x in enumerate(b)) # 0.0262616684...
roll = int(v * 10000) / 100 # 2.62
The first four bytes are 06 b9 15 af — decimal 6, 185, 21, 175. The base-256 cascade gives 0.0262616684, and floor(0.0262616684 × 10000) / 100 = 2.62. A bet of “under 50.00” wins. Run the same code with the same three inputs on any machine and you get 2.62, which is exactly the property that makes the result auditable.
Why four bytes and not modulo
A tempting shortcut is int(digest[:8], 16) % 10000. It works, but 10,000 does not divide 2³², so some outcomes are reachable by one more integer than others. The imbalance is 429,497 versus 429,496 preimages per outcome — a relative bias of about 0.00023%.
That is four orders of magnitude below the 1% house edge, so it is not where your money goes. The base-256 cascade is the convention anyway, and using more bytes shrinks the residual further. Worry about the payout formula, not the rounding.
The payout formula and where the edge lives
The multiplier for a chosen win chance w (as a percentage) is:
payout = (100 − houseEdgePercent) / w
With a 1% edge that is 99 / w. The expected return per unit staked follows immediately:
EV = (w / 100) × (99 / w) = 99 / 100 = 0.99
The w cancels. There is no slider position where it does not cancel. This is the same structure that governs the crash multiplier curve, where the probability of reaching a target and the payout at that target are exact reciprocals scaled by the edge.
| Win chance | Payout at 1% edge | Return per unit staked | House edge |
|---|---|---|---|
| 98.00% | 1.010204× | 0.9900 | 1.00% |
| 95.00% | 1.042105× | 0.9900 | 1.00% |
| 90.00% | 1.100000× | 0.9900 | 1.00% |
| 75.00% | 1.320000× | 0.9900 | 1.00% |
| 50.00% | 1.980000× | 0.9900 | 1.00% |
| 49.50% | 2.000000× | 0.9900 | 1.00% |
| 25.00% | 3.960000× | 0.9900 | 1.00% |
| 10.00% | 9.900000× | 0.9900 | 1.00% |
| 5.00% | 19.800000× | 0.9900 | 1.00% |
| 2.00% | 49.500000× | 0.9900 | 1.00% |
| 1.00% | 99.000000× | 0.9900 | 1.00% |
| 0.10% | 990.000000× | 0.9900 | 1.00% |
| 0.01% | 9900.000000× | 0.9900 | 1.00% |
Note the 49.50% row. That is the setting that pays exactly 2.00×, and it is the dice equivalent of cashing crash out at 2.00× — same win probability, same payout, same 99% return. It is also the configuration most martingale systems assume, which is worth knowing before you read anyone’s staking spreadsheet.
Why every slider position is the same bet
Expected value is constant, so the choice you are making is entirely about variance. Consider three players each staking 1,000 units in total, in single units:
- 90% win chance, 1.10× payout. Roughly 900 wins of +0.10 and 100 losses of −1.00. Expected result: −10 units. Individual sessions cluster tightly around it.
- 50% win chance, 1.98× payout. Roughly 500 wins of +0.98 and 500 losses of −1.00. Expected result: −10 units, with much wider dispersion.
- 1% win chance, 99× payout. Roughly 10 wins of +98 and 990 losses. Expected result: −10 units, and the median result is far worse than the mean because most 1,000-round runs contain fewer than 10 wins while a few contain many more.
The high win-chance settings feel safe and are not: at 90% you need ten wins to pay for one loss, so a stretch of three losses in twenty rounds — perfectly ordinary — puts you behind. The low win-chance settings feel like lottery tickets and mathematically are. The difference between house edge and the distribution it hides is the whole reason both feel wrong to their players for opposite reasons.
Over versus under, and the boundary
The roll grid has exactly 10,000 outcomes: 0.00, 0.01, … 99.99. Win chances are counts on that grid, not continuous percentages.
| Bet | Winning rolls | Count | Win chance |
|---|---|---|---|
| Under 50.00 | 0.00 – 49.99 | 5,000 | 50.00% |
| Over 50.00 | 50.01 – 99.99 | 4,999 | 49.99% |
| Under 2.00 | 0.00 – 1.99 | 200 | 2.00% |
| Over 98.00 | 98.01 – 99.99 | 199 | 1.99% |
The target value itself loses for the over bet and is already excluded from the under bet, so “over X” is always one outcome short of the mirror-image “under X”. The payout adjusts with it — at 49.99% the 1% edge multiplier is 1.980396× rather than 1.980000× — so the edge stays at 1% either way. It is not a trap, but it does mean a screenshot showing 49.99% next to 50.00% is correct rather than buggy.
Checking a site’s dice table
Two arithmetic checks, no tooling needed.
Check the edge is where it claims to be. Multiply the displayed win chance by the displayed payout. You should get 0.99 for a 1% edge. If you get 0.98, the edge is 2% regardless of what the FAQ page says. Do it at three or four slider positions, including an extreme one — a mismatch at 0.5% win chance while 50% checks out means the payout is being capped, which is a real cost you should see before you rely on it.
Check the roll derivation. Take a settled bet, get the revealed server seed, and recompute the roll with the four-byte cascade. The full procedure, including the seed-rotation step that makes the reveal meaningful, is in how to verify a provably fair bet.
If both checks pass, you have confirmed the game is what it says: a 99% return with a slider that trades win rate against payout size. What neither check can tell you is whether the operator will honour a withdrawal, which is a different category of risk and one that no amount of hash verification addresses.
Frequently asked questions
How does the dice game work on crypto casinos?
You pick a target number between 0.00 and 99.99 and bet that the roll lands over or under it. The roll comes from an HMAC-SHA256 of the server seed, client seed and nonce, converted to a number on that scale. Your payout multiplier is set by your chosen win chance, so a narrower target pays more.
What is the payout formula for dice?
Payout multiplier equals (100 minus the house edge percentage) divided by the win chance percentage. With the common 1% edge that is 99 ÷ win chance: a 50% win chance pays 1.98×, 25% pays 3.96×, 2% pays 49.50×. The formula is the only place the edge appears in the game.
Does changing the dice win chance change the house edge?
No. The payout is constructed so that win chance multiplied by payout equals 0.99 at every setting. A 98% win chance and a 0.01% win chance both return 99 cents per dollar staked in expectation. What changes is the shape of your results, not the long-run rate at which the balance drains.
Is rolling under better than rolling over in dice?
They are equivalent when the win chances match, but the same target number does not give the same win chance on both sides. Under 50.00 wins on 5,000 of the 10,000 possible rolls (50.00%), while over 50.00 wins on 4,999 (49.99%), because the boundary value itself is a loss for the over bet.
Can you predict the next dice roll?
Not without the unrevealed server seed. Each roll is a fresh HMAC over an incremented nonce, and a one-character change to the input produces an unrelated digest. Once the server seed is revealed you can recompute every past roll exactly, which is the point of the system, but that gives you no information about future ones.
What is the maximum dice payout?
It depends on the minimum win chance the operator allows. At a 1% edge, a 0.01% win chance implies a 9,900× payout, and that is a common ceiling. Operators set the floor on win chance themselves, so the maximum multiplier varies — check the payout the interface shows rather than assuming a standard.