Skip to main content

The Stake Allocation Formula

Every epoch, shMonad calculates how much pooled stake each validator should receive. v1.2 uses a split weighted-revenue signal rather than one undifferentiated revenue number.

The Core Principle​

Validators should gain pooled stake when they produce strong protocol revenue, and lose pooled stake when their current stake is high relative to their allocation signal.

The v1.2 formula has three main ideas:

  • Staking yield and non-staking revenue are measured separately.
  • Staking yield is adjusted by a deadband so validators do not get excessive allocation credit just because they already have stake.
  • Non-staking revenue receives a configurable multiplier because it is a stronger performance signal for MEV, donations, ACE, and other boost-style revenue.

Weighted Revenue​

For each validator, the protocol computes:

Expected Yieldi=Global Staking Yield×Signal StakeiTotal Signal Stake\text{Expected Yield}_i = \text{Global Staking Yield} \times \frac{\text{Signal Stake}_i}{\text{Total Signal Stake}} Adjusted Yieldi=max⁡(Staking Yieldi−Expected Yieldi×d10,000,0)\text{Adjusted Yield}_i = \max(\text{Staking Yield}_i - \text{Expected Yield}_i \times \frac{d}{10{,}000}, 0) Wi=Adjusted Yieldi+m×Non-Staking RevenueiW_i = \text{Adjusted Yield}_i + m \times \text{Non-Staking Revenue}_i

Where:

  • WiW_i is the validator's weighted allocation signal.
  • dd is the staking-yield deadband in basis points. The v1.2 default is 8,000 bps, so the formula subtracts 80% of expected yield.
  • mm is the non-staking revenue multiplier. The v1.2 default is 2x.
  • Signal stake is pooled target stake, plus isolated snapshot stake only if isolated rewards are included in the allocation signal.

Both revenue buckets are smoothed over the last two completed allocation windows before the formula is applied.

Increasing Stake​

When the protocol has MON to delegate, each validator receives a share based on weighted revenue:

Stake Increasei=Global Queue To Stake×Wi∑W\text{Stake Increase}_i = \text{Global Queue To Stake} \times \frac{W_i}{\sum W}

If total weighted revenue is zero, the protocol cannot make a revenue-based allocation and delays or rolls the stake according to queue rules.

Decreasing Stake for User Withdrawals​

When users request withdrawals, non-turnover withdrawals are routed by available unstakable capacity:

Withdrawal Decreasei=Non-Turnover Queue For Unstake×Validator Available To UnstakeiGlobal Available To Unstake\text{Withdrawal Decrease}_i = \text{Non-Turnover Queue For Unstake} \times \frac{\text{Validator Available To Unstake}_i}{\text{Global Available To Unstake}}

This keeps user withdrawal demand proportional to actual available stake instead of overloading a single validator.

Decreasing Stake for Turnover​

shMonad also creates a small amount of incentive-alignment turnover so stale allocations can move toward currently better performers. Turnover is routed by overallocation:

Overallocationi=max⁡(Current Stakei−Ideal Weighted Stakei,0)\text{Overallocation}_i = \max(\text{Current Stake}_i - \text{Ideal Weighted Stake}_i, 0) Turnover Decreasei=Turnover Queue For Unstake×OverallocationiTotal Overallocation\text{Turnover Decrease}_i = \text{Turnover Queue For Unstake} \times \frac{\text{Overallocation}_i}{\text{Total Overallocation}}

A validator with stake but zero weighted revenue can be treated as fully overallocated, which lets stake rotate away from validators that stopped producing allocation signal.

Netting Into One Action​

The protocol combines the three components into one validator action:

Net Changei=Stake Increasei−(Withdrawal Decreasei+Turnover Decreasei)\text{Net Change}_i = \text{Stake Increase}_i - (\text{Withdrawal Decrease}_i + \text{Turnover Decrease}_i)
  • If the net change is positive, the validator receives more stake.
  • If the net change is negative, the validator has stake withdrawn.
  • If the values net to zero, no validator stake movement is needed.

Round Snapshots​

Allocation is split between a global crank and validator cranks. The global crank snapshots totals and scoring parameters before any validator-specific stake deltas execute.

This means every validator in the same allocation round uses the same:

  • Total pooled target stake
  • Total allocation signal stake
  • Total adjusted weighted revenue
  • Total overallocated stake
  • Non-staking revenue multiplier
  • Staking-yield deadband

The snapshot design prevents a validator cranked early in the loop and a validator cranked late in the loop from using different denominators.

Upgrade Bridge​

During the v1.2 upgrade transition, the protocol can use legacy earned-revenue weighting until the split staking-yield and non-staking revenue buckets are populated. The live upgrade sets the split start round to the upgrade internal epoch plus 3.

After that bridge, allocation uses the v1.2 split formula.