Skip to main content

Staking Behavior

Overview for Users

Monad uses staking to determine the voting weights and leader schedule in MonadBFT. Validators must stake at least a minimum amount, plus others can delegate to them.

When a block is produced, the leader who produced that block earns a block reward, which is distributed to each delegator of that leader, pro rata to their portion of that leader's stake, minus a commission.

Here's what you need to know as a user:

FeatureDetails
In-protocol delegationSupported
Validator commissionEach validator sets a fixed percentage of the block reward to keep for themselves before sharing the rest of the reward prorata by stake.

You should choose a validator that you trust whose commission you're happy with.

The min commission is 0%, the max commission is 100%.
Source of rewardsSuccessful proposal of a block by a leader earns a reward from two components: (1) a fixed reward derived from inflation (REWARD), and (2) the priority fees from all the transactions in the block.
Inflationary rewardThe fixed reward (REWARD) is shared among all delegators of that validator after deducting the validator commission.

As a delegator, your proportion of the remainder is your proportion of the total stake on that validator.

For example: if you have delegated to a validator and comprise 20% of that validator's total stake, the reward for that block is 10 MON, and the commission is 10%, then you would receive 10 MON * 90% * 20% = 1.8 MON.
Priority feesCurrently, priority fees only go to the validator. Validators may choose to donate their priority fees back to the delegators (including themselves) by using the externalReward method on the staking precompile.
EpochAn epoch is every 50,000 blocks (roughly 20,000 seconds, or 5.5 hours). Although you may initiate delegation/undelegation at any time, these actions only take effect at the start of a new epoch.
Boundary blockEach epoch, the boundary block is the block EPOCH_DELAY_PERIOD blocks before the end of the epoch.
Stake activationNew delegations made in epoch n become active at the start of epoch n+1 (if submitted before the boundary block) or epoch n+2 (if not).
Stake deactivationTokens unstaked in epoch n become inactive at the start of epoch n+1 (if submitted before the boundary block) or epoch n+2 (if not).

Upon becoming inactive, this stake moves into a pending state for WITHDRAWAL_DELAY epochs before it is withdrawable.

When it becomes withdrawable, you have to submit a withdraw command to move the MON back to your account.
Reward claiming / compoundingEach delegation accumulates rewards. You can choose either to claim or compound any accumulated rewards.

Claimed rewards get withdrawn to your account, while compounded rewards are added to your delegation.
Active validator setValidators
  • must have self-delegated a minimum amount (MIN_VALIDATE_STAKE)
  • must have a total delegation of at least a certain amount (ACTIVE_VALIDATOR_STAKE), and
  • must be in the top NUM_ACTIVE_VALIDATORS validators by stake weight
in order to be part of the active validator set.

Constants

ConstantMeaningValue
EPOCH_LENGTHepoch length50,000 blocks
EPOCH_DELAY_PERIODnumber of blocks between the boundary block and the end of each epoch5,000 blocks
WITHDRAWAL_DELAYnumber of epochs before unstaked tokens can be withdrawn1 epoch
MIN_VALIDATE_STAKEmin amount of MON self-delegated by a validator for it to be eligible for the active setTBD
ACTIVE_VALIDATOR_STAKEmin amount of MON staked with a validator for it to be eligible for the active setTBD
NUM_ACTIVE_VALIDATORSnumber of validators in the active set200
REWARDMON reward per blockTBD

Consensus and Execution

Monad nodes are split into consensus and execution components. The validator set is maintained by the execution component; all staking-related state changes are queued and applied deterministically in the execution system. The result of these changes is accepted by the consensus component when a predefined block finalization criterion is satisfied.

Definitions

Consider the timeline below, which spans hundreds of thousands of rounds (each round in MonadBFT is 400 ms):

timeline showing the placement of boundary blocks within an epoch

A. Epoch: a range of rounds during which the validator set remains unchanged.

  • In the diagram above, the epochs are the intervals [0, 1], [1, 2], [2, 3], and so on. We refer to them by the starting index; for example, epoch 0 is [0, 1].

B. Boundary block: the block marking the initial point of the end of an epoch. The epoch does not end at the boundary block; also the boundary block is finalized before the next epoch begins.

  • In the diagram above, blocks a, b, c, and d are the boundary blocks of epochs 0, 1, 2, 3, respectively.

C. Epoch delay period: the period of time between a boundary block and the starting round of the next epoch, comprising EPOCH_DELAY_PERIOD blocks.

  • In the diagram above, the epoch delay period for epoch 0 is [a, 1].

  • Note: the staking precompile has a boolean in_boundary indicating whether the current round is within the epoch delay period.

D. Snapshot interval: the range between two consecutive boundary blocks. All staking requests in a snapshot interval take effect at the next epoch after the terminal boundary block.

  • In the diagram above, the snapshot intervals are [a, b], [b, c], [c, d].

The staking contract maintains three views of the validator set:

A. Execution view

  • The Monad client's execution component is responsible for rewards, slashing, and delegation. These actions are processed in real-time on every block, forming the execution view.
  • Actions in each snapshot interval are applied at the next boundary block.

B. Consensus view

  • The consensus view is a frozen copy of the execution view taken at the boundary block.
  • The static validator set of a consensus view formed at the boundary block of epoch n will be the effective validator set for epoch n+1 that starts in EPOCH_DELAY_PERIOD rounds.

C. Snapshot view

  • The snapshot view is the previous consensus view. This is needed for consensus during the epoch delay period.

Intuition on State Changes

Below is an intuitive example of the lifecycle of a transaction in the staking module. Suppose we fix a snapshot interval m in epoch n.

1. Prior to the boundary block

  • Prior to the boundary block, various transactions invoke the addValidator, delegate, undelegate, syscallReward, syscallOnEpochChange, and syscallSnapshot operations.
  • These requests immediately update the execution view of the validator set.
    • addValidator, delegate , undelegate , and syscallSnapshot affect consensus in the next epoch n+1.
    • syscallReward and syscallOnEpochChange have an effect on execution in the current epoch n.

2. Boundary block

  • At the boundary block, syscallSnapshot is called, updating the consensus view of the validators.
  • This view is the set of validators which will be able to participate in consensus during epoch n+1.

3. During the epoch delay period

  • During the epoch delay period, transactions can call addValidator, delegate, undelegate, and syscallReward`.
  • These requests occur in snapshot interval m+1. So they will not have an effect on the Consensus View until epoch n+2.

4. EPOCH_DELAY_PERIOD rounds after the boundary block

  • Start of epoch n+1.
  • The consensus view of the validator set is now the consensus view from snapshot in epoch n.
  • The snapshot view of the validator set is now the consensus view of the validator set from epoch n-1.
  • Execution view of the validator set is up to date.