Block Mining (5x5 Grid + Chainlink VRF)
Block Mining is MINERAL's second mining mechanism — a 5x5 grid lottery where players deploy ETH onto squares and a verifiably random winner is selected every ~60 seconds using Chainlink VRF v2.5.
Overview
| Parameter | Value |
|---|---|
| Grid Size | 5x5 (25 squares) |
| Round Duration | 30 blocks (~60 seconds on Base) |
| Intermission | 5 blocks (~10 seconds between rounds) |
| Minimum Deploy | 0.001 ETH per transaction |
| Maximum Deploy | 100 ETH per transaction |
| Winner Payout | 90% of total pool |
| Motherlode Odds | 1 in 625 per round |
| Randomness Source | Chainlink VRF v2.5 |
How a Round Works
Each round follows a precise lifecycle:
┌─────────────────────────────────────────────────────────────────┐
│ ROUND LIFECYCLE │
│ │
│ DEPLOY PHASE SETTLEMENT CLAIM PHASE │
│ (30 blocks) (VRF callback) (anytime after) │
│ │
│ Users deploy ETH → VRF selects → Winners claim │
│ onto squares winning square their ETH │
│ │
│ ├── 5 blocks ──┤ │
│ INTERMISSION │
│ (next round starts) │
└─────────────────────────────────────────────────────────────────┘
Phase 1: Deploy (30 blocks, ~60 seconds)
Players deploy ETH onto one or more squares on the 5x5 grid:
- Call
deploy([0, 5, 12, 24])with ETH attached - Your ETH is split evenly across your selected squares
- If there's a remainder (ETH doesn't divide evenly), the extra wei goes to the first square in your list
- You can deploy multiple times during a round (amounts accumulate)
- Multiple players can deploy on the same square
Grid Layout:
┌────┬────┬────┬────┬────┐
│ 0 │ 1 │ 2 │ 3 │ 4 │
├────┼────┼────┼────┼────┤
│ 5 │ 6 │ 7 │ 8 │ 9 │
├────┼────┼────┼────┼────┤
│ 10 │ 11 │ 12 │ 13 │ 14 │
├────┼────┼────┼────┼────┤
│ 15 │ 16 │ 17 │ 18 │ 19 │
├────┼────┼────┼────┼────┤
│ 20 │ 21 │ 22 │ 23 │ 24 │
└────┴────┴────┴────┴────┘
Phase 2: Settlement
After the round's 30 blocks have passed, anyone can call settle():
- The contract requests a random number from Chainlink VRF v2.5
- Chainlink's oracle network generates a verifiably random number
- The VRF callback delivers the random word to the contract
- Two decisions are computed from the random word:
Winning Square = randomWord % 25 (lower 128 bits)
Motherlode Hit = (randomWord >> 128) % 625 == 0 (upper 128 bits)
- Revenue is distributed:
- 90% allocated to the winner pool
- 3% added to the Motherlode jackpot
- 3% sent to StakingVault
- 4% sent to Treasury
Phase 3: Claim
After settlement, miners who deployed on the winning square can claim their share:
Your Claim = winnerPool * yourDeployOnWinningSquare / totalDeployOnWinningSquare
Winnings are proportional to how much ETH you deployed on the winning square relative to all deployments on that square.
Revenue Distribution (90-3-3-4)
| Recipient | Share | Description |
|---|---|---|
| Winners | 90% | Split among miners on the winning square, proportional to deployment |
| Motherlode | 3% | Accumulates in jackpot pool (1/625 chance to trigger) |
| StakingVault | 3% | ETH rewards for MINERAL stakers |
| Treasury | 4% | Protocol development fund |
90% to winners is the highest payout ratio among comparable mining protocols.
Revenue Flow
Total ETH deployed in round
│
├── 90% → Winner Pool
│ └── Proportional to deployment on winning square
│
├── 3% → Motherlode Pool
│ └── Accumulates across rounds, 1/625 chance per round
│
├── 3% → StakingVault.fundRewards()
│ └── Distributed to stakers by tier weight
│
└── 4% → Treasury
└── Protocol development
The Motherlode
The Motherlode is a progressive jackpot that grows with every Block Mining round.
How It Accumulates
- 3% of every round's total deployed ETH is added to the Motherlode pool
- The pool grows continuously, round after round
- There is no cap on the Motherlode size
How It Triggers
Each round, after the winning square is determined, a second check is performed:
motherlodeTriggered = (randomWord >> 128) % 625 == 0
- Uses the upper 128 bits of the VRF random word (independent from square selection)
- Probability: 1 in 625 per round (~0.16%)
- At ~60 seconds per round, expected trigger: roughly once every 10.4 hours of continuous play
What Happens on a Motherlode Hit
When the Motherlode triggers:
- The entire accumulated Motherlode pool is added to the winner pool for that round
- Winners on the winning square receive their normal 90% share plus the Motherlode amount
- The Motherlode resets (the 3% from the current round starts the new accumulation)
- A
MotherlodeHitevent is emitted
Example
Round 500:
Total Deployed: 5 ETH
Motherlode Pool (accumulated): 50 ETH
VRF Result: Square 7 wins, Motherlode TRIGGERED
Normal Winner Pool: 5 ETH * 90% = 4.5 ETH
Motherlode Bonus: 50 ETH
Total Winner Pool: 54.5 ETH (!)
If you deployed 1 ETH on Square 7 and total on Square 7 was 2 ETH:
Your Claim: 54.5 * (1/2) = 27.25 ETH
No-Winner Rollover
A critical edge case: what if the winning square has zero deployers?
The Problem
In early rounds with few participants, many squares may be empty. If VRF selects an empty square, the winner pool would have no one to claim it.
The Solution
When the winning square has zero deployments:
if (totalDeployOnWinningSquare == 0):
winnerPool + motherlodeFee → Motherlode Pool
round.winnerPool = 0
- The entire winner pool rolls into the Motherlode
- If a Motherlode was also triggered, the Motherlode amount also rolls forward
- Nothing is locked or lost
- The Motherlode grows faster, increasing the jackpot incentive
- A
NoWinnerRolloverevent is emitted for transparency
This ensures that no ETH is ever permanently locked in the protocol.
VRF Integration Details
Request Flow
Round ends (block.number >= roundEndBlock)
│
├── settle() called by anyone (permissionless)
│
├── Contract sends VRF request to Chainlink Coordinator
│ └── Parameters: keyHash, subId, confirmations, callbackGasLimit, 1 word
│
├── Chainlink oracle network generates random word + proof
│
├── rawFulfillRandomWords() callback received
│ └── Verifies: requestId matches, coordinator is caller
│
└── _finalizeRound() processes the randomness
├── winningSquare = random % 25
├── motherlodeCheck = (random >> 128) % 625
└── Distribute revenue, emit events
VRF Timeout Recovery
If Chainlink VRF fails to respond (network congestion, subscription issues):
| Parameter | Value |
|---|---|
| Timeout Threshold | 300 blocks (~10 minutes on Base) |
| Recovery Function | reRequestRandomness() |
| Access | Permissionless (anyone can call after timeout) |
After 300 blocks without a VRF response, anyone can call reRequestRandomness() to send a new VRF request. The old request is invalidated, and the contract tracks the new request ID.
This ensures the protocol never gets permanently stuck waiting for VRF.
VRF Configuration
| Parameter | Description |
|---|---|
vrfCoordinator | Chainlink VRF v2.5 coordinator address on Base |
vrfKeyHash | Key hash for the VRF proving key |
vrfSubscriptionId | Pre-funded Chainlink subscription |
vrfRequestConfirmations | Number of block confirmations before fulfillment |
vrfCallbackGasLimit | Gas limit for the callback function |
vrfNativePayment | Whether to pay in native ETH (vs. LINK) |
Safety: VRF configuration cannot be changed while there is an active, non-timed-out VRF request. This prevents configuration manipulation during pending settlements.
Empty Round Optimization
If a round has zero total deployments, settle() skips the VRF request entirely. The round is settled immediately with no winner, no revenue distribution, and no gas cost for VRF. The next round starts without delay.
Claim Mechanics
Standard Claim
After a round is settled, winners call claim(roundId):
claimAmount = winnerPool * userDeployOnWinner / totalOnWinner
Last Claimer Gets Remainder
Due to integer division rounding, tiny dust amounts (wei) can accumulate. The last claimer receives the full remaining balance instead of the calculated amount:
if (winnerClaimCount + 1 == totalWinningMiners):
claimAmount = winnerPool - claimedWinnerPool // gets everything remaining
This ensures that no dust is stranded in the contract.
Claim Tracking
| Variable | Purpose |
|---|---|
claimedWinnerPool | Running total of ETH claimed from this round |
winnerClaimCount | Number of miners who have claimed |
outstandingWinnerClaims | Protocol-wide total of unclaimed winner ETH |
Strategy Guide
Basic Strategies
| Strategy | Description | Risk/Reward |
|---|---|---|
| Single square | Deploy all ETH on one square | High risk, high reward (25:1 if alone) |
| Spread (5 squares) | Deploy across 5 squares | Medium risk, ~20% chance of winning |
| Wide spread (10+) | Deploy across many squares | Lower risk, lower reward per win |
| All 25 | Deploy on every square | Guaranteed win, but only profit from others' deployments |
| Motherlode hunter | Play many rounds, deploy minimal | Low cost, hoping for Motherlode hit |
Advanced Considerations
-
Square selection: There is no "best" square — VRF is truly random. All squares have equal 4% chance of winning.
-
Timing: Deploy as late as possible in the round to see where others have deployed. Deploying on less-crowded squares gives you a larger share if that square wins.
-
Motherlode math: The Motherlode triggers 1 in 625 rounds. If you play 625 rounds, you have a ~63% chance of seeing at least one Motherlode hit (but not necessarily being on the winning square when it hits).
-
Expected value: Deploying on an empty square that wins gives you 90% of the entire pool (minus fees). Deploying on a crowded square means splitting the 90% with others.
AutoMiner — Automated Play
Don't want to manually deploy every 60 seconds? AutoMiner is an on-chain contract that plays Block Mining on your behalf.
How It Works
- Configure — Choose a strategy and set your budget per round
- Deposit — Deposit ETH into the AutoMiner contract
- Sit back — An executor bot deploys for you every round automatically
- Claim — Claim your winnings directly from BlockMining whenever you win
Strategies
| Strategy | Description |
|---|---|
| SPREAD | Deploy equally across all 25 squares every round (safest) |
| RANDOM | Deploy to N random squares each round (configurable) |
| SELECT | Deploy to your chosen squares every round |
Key Parameters
| Parameter | Value |
|---|---|
| Minimum Budget | 0.001 ETH per round |
| Maximum Budget | 10 ETH per round |
| Auto-deactivation | When balance falls below budget |
| Re-activation | Deposit more ETH or call activate() |
Architecture
User configures strategy + deposits ETH
│
├── AutoMiner contract holds user funds
│
├── Executor bot monitors rounds (off-chain)
│ └── Every ~60s: calls executeAll()
│
├── AutoMiner calls BlockMining.deployFor(user, squares)
│ └── Position recorded under user's address
│
└── User claims winnings from BlockMining directly
deployFor() — Third-Party Deployment
BlockMining supports a deployFor(address miner, uint8[] squares) function:
- Permissionless — anyone can deploy on behalf of anyone else
- The caller pays the ETH
- The position is recorded under the miner's address
- The miner claims their own winnings
This is the mechanism that enables AutoMiner and future AI agent integrations.
Technical Details
Contract Parameters
| Parameter | Value | Type |
|---|---|---|
GRID_SIZE | 25 | constant |
ROUND_DURATION | 30 blocks | constant |
INTERMISSION | 5 blocks | constant |
WINNER_BPS | 9000 (90%) | constant |
MOTHERLODE_BPS | 300 (3%) | constant |
STAKING_BPS | 300 (3%) | constant |
TREASURY_BPS | 400 (4%) | constant |
MOTHERLODE_ODDS | 625 | constant |
MIN_DEPLOY | 0.001 ETH | constant |
MAX_DEPLOY_PER_TX | 100 ETH | constant |
VRF_REQUEST_TIMEOUT_BLOCKS | 300 | constant |
ADDRESS_UPDATE_DELAY | 1 day | constant |
Security Features
- ReentrancyGuard on all state-modifying functions
- Pausable — Owner can pause deploys in emergencies
- Chainlink VRF — Tamper-proof randomness
- VRF timeout recovery — Permissionless re-request after 300 blocks
- No-winner rollover — No funds ever locked
- Last claimer remainder — No dust stranded
- Tracked balance — All obligations accounted on-chain
- 1-day timelock — Admin address changes require 24-hour delay
- receive() reverts — Contract cannot receive direct ETH transfers
- Ownable2Step — Two-step ownership transfer