# Lucky Ledger: Provably fair crypto dice casino

A crypto casino on Polygon where bets settle in milliseconds, cost no gas, and every roll can be checked by the player who made it.

*2026 · 2 months*

## The brief

Lucky Ledger is a crypto dice casino on Polygon where players bet USDC on provably fair outcomes. The client came to us wanting everything on-chain, the way trustless casinos are meant to work: randomness from an oracle, every bet settled by the contract. We researched that path properly before committing to it, and it kept hitting the same walls: an oracle call on every bet meant a wallet popup, a fee, and a wait of around fifteen seconds, unusable for a game people play several times a minute.

So we advised a different route and the client agreed: keep the money on-chain, move the game off-chain into a server that commits to its randomness in public, and let any player verify every roll from the site. Faster, no per-bet gas, no oracle exploit, and still provably fair. From there we built the whole thing end to end: game engine, wallet login, database, deposits, withdrawals and admin tooling, live on Polygon mainnet.

## What we built

- **Provably fair engine.** committed seed chain, HMAC-settled rolls
- **Self-serve verifier.** players re-check every past bet themselves
- **Four bet modes.** roll under, over, outside, between, live odds
- **Sign-In with Ethereum.** wallet signature, no passwords or email
- **Deposits.** on-chain events parsed and credited, no double-spend
- **Withdrawals.** reviewed, then batched on-chain, up to 50 at once
- **Admin dashboard.** treasury, game config, players, seasons, payouts
- **Risk controls.** house edge, bet caps, live treasury exposure limit
- **Treasury contract.** upgradeable, pausable, reentrancy-guarded

## How it works

Three layers, one job each: the blockchain handles money, the server handles the game, and cryptography handles trust. A set of authenticated API routes runs the seed chain, the HMAC engine and the risk controls, backed by Postgres where every balance change, a bet, a deposit credit, a withdrawal reservation, happens inside a single row-locked transaction, so a player's balance and their bet record can never disagree. On-chain, one treasury contract holds deposits and pays approved withdrawals in batches. That is all the chain needs to see.

## Stack

- **Frontend:** Next.js, React, TypeScript, Tailwind CSS, shadcn/ui, Radix, TanStack Query
- **Web3 & auth:** wagmi, viem, RainbowKit, ethers, Sign-In with Ethereum, iron-session
- **Backend:** Node API routes, Neon Postgres, Drizzle ORM, Node crypto (SHA-256, HMAC)
- **Contracts:** Solidity, Hardhat, OpenZeppelin (UUPS upgradeable), Chainlink VRF, Polygon mainnet, USDC

## Numbers

- **75x** faster settlement, from ~15s to under 200ms
- **$0** gas paid per bet, deposits and withdrawals aside
- **172** contract tests before any USDC moved on mainnet
- **100k** committed seeds per season, fixed before play
- **2%** house edge, enforced and provably fair
- **50** withdrawals settled in one on-chain transaction

## The hardest part

The real work was the research that reshaped the architecture. Fully on-chain sounds like the safest possible design, but it carries two problems that only surface once you push on it. The first is speed: randomness from an oracle means a round trip on every bet, roughly fifteen seconds, which is unusable for a dice game. The second is subtler and worse. The usual trick to avoid paying for an oracle call every time is to rotate one seed on a timer, but that leaves each bet's outcome fully determined the moment a player signs. Because wallets simulate a transaction before confirming it, a player could preview the result, reject every loss and confirm every win, which quietly breaks the house edge a casino runs on. Fully on-chain was not actually the safe choice.

So we advised moving trust off the chain and into cryptography the player can check, and it turned out faster, cheaper and harder to break. The server builds a chain of a hundred thousand SHA-256 seeds from a single random origin, publishes the final hash as a public commitment before the season opens, and settles each roll with an HMAC of that seed and an input the player supplies. The house is locked into every outcome before a bet exists, and altering a seed afterwards produces a different hash than the one the player was already shown, so cheating would leave a permanent, provable receipt. Players can re-check any past bet themselves from a page on the site, or with standard tools. The chain shrank to a deposit and withdrawal treasury, the per-bet popup disappeared, and settlement dropped from fifteen seconds to under a fifth of one. It is the model high-volume crypto casinos run: the guarantee shifts from impossible to cheat to cheating is cryptographically detectable and publicly provable.

More work: https://dock30.com/work

## Contact

- Email: crew@dock30.com
- Book a call: https://dock30.com/contact
