CONTRACT

Contract details

Source verified. Storage layout published. ABI canonical.

STATUS
Minnow v1.1 (dual-oracle) deployed and verified on Ethereum mainnet. Supra dVRF V3 health-check passed; Chainlink VRF v2.5 wired for the second oracle path. Currently pre-activation · play enables the moment the operator fires activate().

Launch sequence

  1. DONE: Codex audit on locked design
  2. DONE: Hardhat tests covering every state transition
  3. DONE: Mainnet fork tests
  4. DONE: Chainlink VRF v2.5 subscription owned + funded by the contract
  5. DONE: Deploy Minnow to Ethereum mainnet
  6. DONE: Verify on Etherscan + Blockscout
  7. DONE: Live oracle health-check (Supra mainnet callback in ~45s)
  8. CURRENT: Pre-activation · play locked until activate() fires
  9. Operator fires activate()
  10. Anyone fires createRound() (or createRoundAndEnter() with branding) to open round #001 · pot starts from player entries, no founder pre-seed
  11. Watch #001 settle cleanly
  12. Owner calls freezeAdmin() · pause/unpause permanently disabled (emergency refund path survives the freeze)

Addresses

Bracket constants · Minnow v1 vs Minnow v1.1

Constantv1v1.1
MIN_SLOT_VALUE0.001 ETH0.001 ETH
MAX_SLOT_VALUE0.100 ETH0.100 ETH
SLOT_STEP0.001 ETH0.001 ETH
TOTAL_SLOTS100100
THRESHOLD0.3 ETH (fixed)0.015 → 1 ETH · creator-tunable per round (default 0.05)
SEED_PHASE_MAX6h6h
ACTIVE_TIMER6h (resets)6h (resets)
ACTIVE_PHASE_MAX12h12h
FINAL_COUNTDOWN6h (no resets)6h (no resets)
MAX_POSSIBLE_POT5.050 ETH5.050 ETH
ORACLEChainlink VRF v2.5Dual · Chainlink VRF v2.5 + Supra dVRF V3, first-fulfills-wins
ROUND BRANDINGOn-chain name + image URI
THRONE LEADERBOARD1% of every pot to top 3 creators (90-day season)

Payout splits

WINNER_BPS7150 (71.5%) + keeper cap-rebate + dust
SECOND_BPS650 (6.5%)
THIRD_BPS350 (3.5%)
SEED_BPS1000 (10%)
RAKE_BPS500 (5%) · to $BURN contract
FOUNDER_BPS50 (0.5%) · two-step settable
VRF_REPLENISH_BPS100 (1%) · self-funds both oracle subs
KEEPER_BPS / KEEPER_CAP100 (1%) capped at 0.01 ETH
THRONE_BPS100 (1%) · top 3 leaderboard share (v1.1 only · 70/20/10)
MAX_ENTRIES_PER_ADDRESS50 (per round)
MAX_ENTRIES_PER_TX10 (enterBatch cap)
VRF_RETRY_BOUNTY0.0001 ETH per requestRandomnessAgain call
MAX_REQUESTS_PER_ORACLE3 total per oracle · 1 initial + up to 2 retries
VRF_RETRY_TIMEOUT30 min after each oracle request
EMERGENCY_REFUND_DELAY72h from stuck timestamp · survives freezeAdmin

v1.1 sum: 71.5 + 6.5 + 3.5 + 10 + 5 + 0.5 + 1 + 1 + 1 = 100%. (v1 omits the 1% throne slice; its winner pulls 72.5% instead of 71.5%.)

Key entry-point functions

createRound()Open a new round · permissionless (post-activate)
enter(roundId, slotIndex)Claim a slot · payable · msg.value must equal slot price
enterBatch(roundId, slotIndex[])Up to 10 slots in one tx · payable · msg.value = sum of slot prices
settle(roundId)Fires VRF request · permissionless · no keeper bounty (only fires the request)
rawFulfillRandomWords(...)Chainlink VRF callback · only callable by VRF coordinator
finalizeSettlement(roundId)Ranks top 3, credits payouts, sends $BURN rake, EARNS the keeper bounty
requestRandomnessAgain(roundId)Re-requests VRF · 30min cooldown · capped at 3 total requests per round
withdrawPayout(roundId)Winner / 2nd / 3rd / founder / keeper pull their share for that round
withdrawSeedDividend(roundId)Seed contributors pull their pro-rata slice for that round
withdrawRefund(roundId, slotIndex)Refund per-slot · one call per slot owned in a refunded round
emergencyResolveStuckRound(roundId)Owner-only · flips a stuck round to refund-eligible · no recipient/amount params, no drain · 72h delay
freezeAdmin()One-way · permanently disables pause/unpause · emergency refund path SURVIVES