Skip to main content

Staking (5-Tier System)

MINERAL features a 5-tier staking system where token holders lock MINERAL to earn real ETH yield from protocol mining revenue.


Overview​

ParameterValue
Tiers5 (Flex, Bronze, Silver, Gold, Diamond)
Reward TokenETH (not MINERAL — real yield)
Revenue Sources3% of Auction Mining + 3% of Block Mining
Claim Cooldown2 days after staking
Penalty RecipientTreasury

Key distinction: MINERAL staking pays rewards in ETH, not inflationary token emissions. Rewards come directly from protocol mining revenue — real economic activity.


The Five Tiers​

TierNameLock PeriodEarly Unstake PenaltyReward Allocation
0FlexNone (0 days)0%10%
1Bronze7 days5%10%
2Silver30 days10%20%
3Gold180 days25%25%
4Diamond365 days40%35%
Total:100%

Tier Mechanics Explained​

Lock Period: The minimum time your tokens must remain staked. Each new stake extends the lock to now + lockDuration if that's later than your current lock end.

Early Unstake Penalty: If you unstake before the lock period expires, a percentage of your unstaked amount is taken as a penalty and sent to the treasury.

Reward Allocation: When ETH rewards arrive, they're distributed across tiers based on allocation weight * total staked in that tier (see reward formula below).

Example Scenarios​

Flex Tier:

  • Stake and unstake anytime, no penalty, no lock
  • Lowest reward allocation (10%), but maximum flexibility
  • Good for users who want exposure without commitment

Diamond Tier:

  • Lock for 365 days, 40% penalty if you leave early
  • Highest reward allocation (35%)
  • Best for long-term conviction holders
  • Penalty example: unstake 1000 MINERAL early → receive 600, treasury gets 400

How Rewards Work​

Revenue Flow​

Auction Mining (3% of revenue)  ──┐
├──→ StakingVault.fundRewards()
Block Mining (3% of revenue) ──┘
│
├── Tier 0 (Flex): 10% weighted
├── Tier 1 (Bronze): 10% weighted
├── Tier 2 (Silver): 20% weighted
├── Tier 3 (Gold): 25% weighted
└── Tier 4 (Diamond): 35% weighted

Reward Distribution Formula​

When ETH arrives via fundRewards(), it's split across tiers based on effective stake weight:

For each tier:
effectiveStake = totalStakedInTier * allocationBps

Total effective: sum of all tiers' effectiveStake

Tier's share = incomingETH * tierEffectiveStake / totalEffectiveStake

Within each tier, rewards are distributed pro-rata based on individual stake:

Your reward = tierETH * yourStake / totalStakedInTier

This is implemented using an accumulator pattern (O(1) gas cost per claim, regardless of number of stakers):

accEthPerShare += reward * 1e18 / totalStakedInTier
pendingReward = (userStake * accEthPerShare / 1e18) - userDebt

ETH Buffer​

If no tokens are staked in any tier (protocol launch scenario), incoming ETH is stored in a buffer. When the first user stakes, the buffer is distributed.

This ensures no ETH is ever lost during the bootstrap period.


Staking Lifecycle​

Step 1: Stake​

stake(tier, amount)
  • Transfer MINERAL tokens to StakingVault
  • Lock timer starts (or extends if already staked in this tier)
  • Begin earning ETH rewards immediately
  • Claim cooldown: cannot claim or unstake for 2 days after staking

Step 2: Earn​

  • ETH rewards accumulate automatically as mining activity generates revenue
  • No action needed — rewards accrue to your account in real time
  • View pending rewards anytime via pendingRewards(user, tier) or pendingRewardsAll(user)

Step 3: Claim​

claim(tier, to)     // claim from specific tier
claimAll(to) // claim from all tiers at once
  • Receive ETH to your wallet (or another address)
  • Must wait 2 days after your most recent stake (per tier)
  • claimAll() skips tiers that are still in cooldown (doesn't revert)
  • Claiming does not unstake your tokens — you continue earning

Step 4: Unstake​

unstake(tier, amount)
  • Withdraw your MINERAL tokens
  • If lock period has not expired: penalty applied
  • If lock period has expired: full amount returned
  • Pending rewards are automatically claimed during unstake
  • Full unstake resets your lock timer to zero

Penalty System​

How Penalties Work​

ConditionResult
Unstake after lock expiresFull amount returned (0% penalty)
Unstake before lock expirespenalty = amount * penaltyBps / 10000
Penalty destinationTreasury address
Penalty tokensRemain as MINERAL (not burned)

Penalty Examples​

TierStakeUnstake EarlyYou ReceiveTreasury Gets
Flex1000Anytime10000
Bronze1000Before 7 days95050
Silver1000Before 30 days900100
Gold1000Before 180 days750250
Diamond1000Before 365 days600400

Lock Extension Rule​

If you stake additional tokens while already staked:

  • New lock end = max(currentLockEnd, now + lockDuration)
  • Only extends if the new end time is later than the current one
  • You cannot "reset" a lock by staking a tiny amount

2-Day Claim Cooldown​

After staking, you must wait 2 days (172,800 seconds) before you can:

  • Claim rewards
  • Unstake tokens

Why? This prevents flash-loan attacks where someone:

  1. Borrows a large amount of MINERAL
  2. Stakes it
  3. Claims accumulated rewards
  4. Unstakes and repays the loan

The 2-day cooldown makes this economically infeasible.


Strategy Guide​

Tier Selection​

Your GoalRecommended TierWhy
Maximum flexibilityFlexNo lock, no penalty, earn 10% allocation
Short-term yieldBronze7-day lock, low penalty, reasonable allocation
Balanced approachSilver30-day lock, 20% allocation, 10% penalty
Long-term convictionGold180-day lock, 25% allocation
Maximum yieldDiamond365-day lock, 35% allocation, highest rewards

Yield Optimization​

  1. Higher tiers earn more per token staked — the allocation weights are not proportional to lock duration. Diamond's 35% allocation with a 365-day lock is more capital efficient than Flex's 10% with no lock.

  2. Early penalty is binary — you either pay the penalty or you don't. There's no graduated penalty based on how early you leave. Unstaking 1 day into a Gold lock costs the same as unstaking 179 days in.

  3. Multiple tiers — You can stake in multiple tiers simultaneously. For example, put 50% in Diamond (conviction) and 50% in Flex (liquidity).

  4. claimAll() is gas efficient — Claims from all tiers in one transaction. Skips cooldown tiers automatically.

APY Estimation​

Staking APY depends on:

  • Total mining revenue (ETH flowing in)
  • Your stake relative to total stake in your tier
  • Your tier's allocation weight
  • Protocol activity level
Estimated APY = (annualRevenueToStaking * tierAllocation * yourShare) / yourStakeValue

There is no fixed APY — it fluctuates based on mining activity. More miners = more revenue = higher staking yield.


Technical Details​

Contract: StakingVault​

ParameterValue
TIER_COUNT5
MIN_CLAIM_DELAY2 days (172,800 seconds)
PRECISION1e18 (accumulator precision)

View Functions​

FunctionReturns
pendingRewards(user, tier)Pending ETH for a user in a specific tier
pendingRewardsAll(user)Total pending ETH across all tiers
getUserStake(user, tier)(staked, lockEndTime, pending, isLocked)
getTierInfo(tier)(totalStaked, allocationBps, lockDuration, penaltyBps)
getAllTierStats()All tier data in arrays
calculatePenalty(user, tier, amount)Preview penalty amount
totalStaked()Protocol-wide total staked
userTotalStaked(user)User's total across all tiers

Security Features​

  • ReentrancyGuard on stake/unstake/claim
  • SafeERC20 for all token transfers
  • 2-day claim cooldown prevents flash-loan exploits
  • receive() reverts — ETH must come through fundRewards()
  • Ownable2Step — Two-step ownership transfer
  • One-time wiring — AuctionMining and BlockMining addresses set once