Verify · recompute a draw

Check a pack yourself

Pick a pack. This page fetches its public data, recomputes the seed commitment, the entropy, the winning ticket, the winner's Merkle proof and all five cards in your browser, and compares every number with what the contract stored. Nothing is sent anywhere.

Pick a pack

What is being checked

commitment = keccak256(abi.encodePacked(uint64 id, bytes32 seed)) entropy = keccak256(abi.encodePacked(seed, blockhash(revealBlock), uint64 id)) ticket = uint256(entropy) % totalTickets winner = leaf with start ≤ ticket < end roll_i = uint256(keccak256(entropy ‖ "tier" ‖ uint8 i)) % 10000 tier_i = <7000 common · <9200 rare · <9900 holo · else chase stock_i = series[ keccak256(entropy ‖ "stock" ‖ uint8 i) % len ] value_i = budget × weight_i / Σweight (remainder → card 1)

The keeper commits keccak256(id ‖ seed) and the Merkle root of the public ticket list when it seals a pack, and picks a reveal block a few L1 blocks in the future. Nobody knows that block's hash at seal time, and the keeper cannot change the seed afterwards.

After the reveal block, settlePack checks the seed against the commitment, reads the block hash on-chain, mixes them into the entropy and derives the winner and the five cards. If a check here is red, the numbers on this site and on the chain disagree. Tell us on X or Telegram.

Robinhood Chain reports the L1 block number to contracts, and its block hash is only readable on-chain for 256 L1 blocks. That is why the seed and blockhash shown here come from the PackSettled event of the draw transaction; the entropy check proves they are the ones the contract used.

Run it from a terminal

Node 18+, no dependencies, its own keccak256
curl -sO https://sealslab.xyz/verify/verify-pack.mjs node verify-pack.mjs 12
Download verify-pack.mjs Options: --api URL · --rpc URL · --vault 0x… · --no-chain
Show the script
Loading…