Skip to content

How to Stake your Tokens

Staking Moonbeam Banner

Introduction

Collator candidates with the highest stake in the network join the active pool of collators (block producers), from which they are selected to offer a block to the relay chain.

Token holders can add to candidates' stake using their tokens, a process called delegation (also referred to as staking). When they do so, they are vouching for that specific candidate, and their delegation is a signal of trust. When delegating, tokens are deducted instantly and added to the total amount staked by the user. Exiting a position is divided into a two step operation: scheduling and execution. First, token holders must schedule a request to exit their position, and wait for a given delay or unbonding period, which depends on the network. Once the unbonding period has expired, users can execute their scheduled action.

Once a candidate joins the active set of collators, they are eligible to produce blocks and receive partial block rewards as part of the token inflationary model. They share these as staking rewards with their delegators, considering their proportional contribution toward their stake in the network.

This guide will show you how to stake on Moonbase Alpha via Polkadot.js Apps, but similar steps can be taken for any of the Moonbeam and Moonriver. Token holders that want to easily stake their tokens can use the Moonbeam dApp to do so.

For more general information on staking, please check out the Staking on Moonbeam overview.

Extrinsics Definitions

There are many extrinsics related to the staking pallet, so all of them are not covered in this guide. However, the following list defines all of the extrinsics associated with the delegation process. After runtime upgrade 1001, some extrinsics were deprecated.

Note

Extrinsics might change in the future as the staking pallet is updated.

Join or Leave The Delegator Set

  • delegate(address candidate, uint256 amount, uint256 candidateDelegationCount, uint256 delegatorDelegationCount) - extrinsic to delegate a collator. The amount needs to be greater than the minimum delegation stake. Replaces the deprecated nominate extrinsic
  • scheduleLeaveDelegators() - extrinsic to schedule to leave the set of delegators. There is an exit delay before you can execute the request via the executeLeaveDelegators extrinsic and actually leave the set of delegators. Replaces the deprecated leaveNominators extrinsic
  • executeLeaveDelegators(uint256 delegatorDelegationCount) - extrinsic to execute and leave the set of delegators. This extrinsic should only be used after a leave has been scheduled and the exit delay has passed. Consequently, all ongoing delegations will be revoked
  • cancelLeaveDelegators() - extrinsic to cancel a scheduled request to leave the set of delegators

The following extrinsics are deprecated:

  • nominate(address collator, uint256 amount, uint256 collatorNominationCount, uint256 nominatorNominationCount) — extrinsic to delegate a collator. The amount needs to be greater than the minimum delegation stake
  • leaveNominators(uint256 nominatorNominationCount) — extrinsic to leave the set of delegators. Consequently, all ongoing delegations will be revoked

Bond More or Less

  • delegatorBondMore(address candidate, uint256 more) - extrinsic to request to increase the amount of staked tokens for an already delegated collator. Replaces the deprecated nominatorBondMore extrinsic
  • scheduleDelegatorBondLess(address candidate, uint256 less) - extrinsic to request to reduce the amount of staked tokens for an already delegated collator. The amount must not decrease your overall total staked below the minimum delegation stake. There will be a bond less delay before you can execute the request via the executeDelegationRequest extrinsic. Replaces the deprecated nominatorBondLess extrinsic
  • executeDelegationRequest(address delegator, address candidate) - extrinsic to execute and pending delegation requests. This extrinsic should only be used after a request has been scheduled and the exit delay has passed
  • scheduleCandidateBondLess(uint256 less) - extrinsic that allows a collator candidate to request to decrease their self bond by a given amount. There will be a bond less delay before you can execute the request via the executeCandidateBondLess extrinsic
  • executeCandidateBondLess(address candidate) - extrinsic to execute a decrease a candidate's self bond amount. This extrinsic should only be used after a bond request has been scheduled and the exit delay has passed
  • cancelCandidateBondLess() - extrinsic to cancel a scheduled request to increase or decrease the bond for a specific candidate

The following extrinsics are deprecated:

  • nominatorBondLess(address collator, uint256 less) — extrinsic to reduce the amount of staked tokens for an already delegated collator. The amount must not decrease your overall total staked below the minimum delegation stake
  • nominatorBondMore(address collator, uint256 more) — extrinsic to increase the amount of staked tokens for an already delegated collator

Revoke Delegations

  • scheduleRevokeDelegation(address collator) - extrinsic to schedule to remove an existing delegation entirely. There will be a revoke delegation delay before you can execute the request via the executeDelegationRequest extrinsic. Replaces the deprecated revokeNomination extrinsic
  • cancelDelegationRequest(address candidate) - extrinsic to cancel a scheduled request to revoke a delegation

The following extrinsic is deprecated:

  • revokeNomination(address collator) — extrinsic to remove an existing delegation

Retrieving Staking Parameters

You can now read any of the current parameters around staking, such as the ones previously listed in the General Definitions section and more, directly from Polkadot.js Apps.

Navigate to Polkadot.js Apps Chain state UI, and for the purposes of this guide, connect to Moonbase Alpha. Alternatively, you can connect to Moonbeam or Moonriver.

Then to retrieve the various staking parameters, you'll need to:

  1. Select the Constants tab on the Chain state UI
  2. From the selected constant query dropdown, choose parachainStaking
  3. Choose any function you would like to get data for. For this example, you can use maxDelegationsPerDelegator. This will return the maximum number of candidates you can delegate
  4. Click + to return the current value

Retrieving staking parameters

You should then see the maximum delegations per delegator, which can also be found in the Staking on Moonbeam overview.

How to Stake via Polkadot.js Apps

This section goes over the process of delegating collator candidates.

The tutorial will use the following candidates on Moonbase Alpha as a reference:

Variable Address
Candidate 1 0x4c5A56ed5A4FF7B09aA86560AfD7d383F4831Cce
Candidate 2 0x623c9E50647a049F92090fe55e22cC0509872FB6

Before staking via Polkadot.js Apps, you need to retrieve some important parameters.

Retrieving the List of Candidates

Before starting to stake tokens, it is important to retrieve the list of collator candidates available in the network. To do so:

  1. Head to the Developer tab
  2. Click on Chain State
  3. Choose the pallet to interact with. In this case, it is the parachainStaking pallet
  4. Choose the state to query. In this case, it is the selectedCandidates or candidatePool state
  5. Send the state query by clicking on the + button

Each extrinsic provides a different response:

  • selectedCandidates — returns the current active set of collators, that is, the top collator candidates by total tokens staked (including delegations). For example, on Moonbase Alpha it is the top 45 candidates
  • candidatePool — returns the current list of all the candidates, including those that are not in the active set

Staking Account

Get the Candidate Delegation Count

First, you need to get the candidateInfo, which will contain the delegator count, as you'll need to submit this parameter in a later transaction. To retrieve the parameter, make sure you're still on the Chain State tab of the Developer page, and then take the following steps:

  1. Choose the parachainStaking pallet to interact with
  2. Choose the candidateInfo state to query
  3. Make sure the include option slider is enabled
  4. Enter the collator candidate's address
  5. Send the state query by clicking on the + button
  6. Copy the result as you'll need it when initiating a delegation

Get candidate delegation count

Get your Number of Existing Delegations

If you've never made a delegation from your address you can skip this section. However, if you're unsure how many existing delegations you have, you'll want to run the following JavaScript code snippet to get delegationCount from within Polkadot.js:

// Simple script to get your number of existing delegations.
// Remember to replace YOUR_ADDRESS_HERE with your delegator address.
const yourDelegatorAccount = 'YOUR_ADDRESS_HERE'; 
const delegatorInfo = await api.query.parachainStaking.delegatorState(yourDelegatorAccount);
console.log(delegatorInfo.toHuman()["delegations"].length);
  1. Head to the Developer tab
  2. Click on JavaScript
  3. Copy the code from the previous snippet and paste it inside the code editor box
  4. (Optional) Click the save icon and set a name for the code snippet, for example, Get existing delegations. This will save the code snippet locally
  5. To execute the code, click on the run button
  6. Copy the result as you'll need it when initiating a delegation

Get existing delegation count

Staking your Tokens

To access staking features, you need to use the Polkadot.js Apps interface. To do so, you need to import/create an Ethereum-style account first (H160 address), which you can do by following the Creating or Importing an H160 Account section of the Polkadot.js guide.

For this example, an account was imported and named with a super original name: Alice. Alice's address is 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac.

Currently, everything related to staking needs to be accessed via the Extrinsics menu, under the Developer tab:

Staking Account

To delegate a candidate, provide the following information:

  1. Select the account from which you want to stake your tokens
  2. Choose the parachainStaking pallet
  3. Choose the delegate extrinsic
  4. Set the candidate's address to delegate. In this case, it is set to 0x4c5A56ed5A4FF7B09aA86560AfD7d383F4831Cce
  5. Set the number of tokens you want to stake
  6. Input the candidateDelegationCount you retrieved previously from querying candidateInfo
  7. Input the delegationCount you retrieved from the JavaScript console. This is 0 if you haven't yet delegated a candidate
  8. Click the Submit Transaction button and sign the transaction

Staking Join Delegators Extrinsics

Note

The parameters used in steps 6 and 7 are for gas estimation purposes and do not need to be exact. However, they should not be lower than the actual values.

Verifying Delegations

Once the transaction is confirmed, you can verify your delegation by navigating to Chain state under the Developer tab.

Staking Account and Chain State

Here, provide the following information:

  1. Choose the pallet you want to interact with. In this case, it is the parachainStaking pallet
  2. Choose the state to query. In this case, it is the delegatorState
  3. Verify the selected address is correct. In this case, you are looking at Alice's account
  4. Make sure to enable the include option slider
  5. Send the state query by clicking on the + button

Staking Chain State Query

In the response, you should see your account (in this case, Alice's account) with a list of the delegations. Each delegation contains the target address of the candidate and the amount.

You can follow the same steps as described to delegate other candidates in the network. For example, Alice delegated 0x623c9E50647a049F92090fe55e22cC0509872FB6 as well.

How to Stop Delegations

As of runtime version 1001, there have been significant changes to the way users can interact with various staking features. Including the way staking exits are handled.

If you want to make an exit and stop a delegation, you have to first schedule it, wait an exit delay, and then execute the exit. If you are already a delegator, you have two options to request to stop your delegations: using the scheduleRevokeDelegation extrinsic to request to unstake your tokens from a specific collator candidate, or using the scheduleLeaveDelegators extrinsic to request to revoke all ongoing delegations. Scheduling a request does not automatically revoke your delegations, you must wait an exit delay and then execute the request by using either the executeDelegationRequest method or the executeLeaveDelegators method.

Schedule Request to Stop Delegations

This example is a continuation of the previous section, and assumes that you have at least two active delegations.

To schedule a request to revoke your delegation from a specific candidate, navigate to the Extrinsics menu under the Developer tab. Here, provide the following information:

  1. Select the account from which you want to remove your delegation
  2. Choose the parachainStaking pallet
  3. Choose the scheduleRevokeDelegation extrinsic
  4. Set the candidate's address you want to remove your delegation from. In this case, it is set to 0x623c9E50647a049F92090fe55e22cC0509872FB6
  5. Click the Submit Transaction button and sign the transaction

Staking Schedule Request to Revoke Delegation Extrinsic

Note

There can only be one pending scheduled request per candidate.

As mentioned before, you can also remove all ongoing delegations with the scheduleLeaveDelegators extrinsic in step 3 of the Extrinsics instructions. This extrinsic requires no input.

Staking Leave Delegators Extrinsic

Once you have scheduled an exit, you must wait an exit delay before you can then execute it. If you try to execute it before the exit delay is up the extrinsic will fail and you'll see an error from Polkadot.js Apps for parachainStaking.PendingDelegationRequest.

Execute Request to Stop Delegations

After the exit delay has passed after initiating the scheduled request, you can go back to the Developer tab of the Extrinsics menu and follow these steps to execute the request:

  1. Select the account to execute the revocation
  2. Choose the parachainStaking pallet
  3. Choose the executeDelegationRequest extrinsic
  4. Set the delegator's address you want to remove the delegation for. For this example, it will be Alice's address 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac
  5. Set the candidate's address you want to remove your delegation from. In this case, it is set to 0x623c9E50647a049F92090fe55e22cC0509872FB6
  6. Click the Submit Transaction button and sign the transaction

Staking Execute Revoke Delegation Extrinsic

If you want to remove all ongoing delegations, you can adapt the Extrinsics instructions to call the executeLeaveDelegators extrinsic:

  1. Select the account to remove all the delegations for
  2. Choose the parachainStaking pallet
  3. Choose the executeLeaveDelegators extrinsic
  4. Enter the total number of all delegations to revoke using the delegationCount you retrieved from the JavaScript console. This is 0 if you haven't yet delegated a candidate
  5. Click the Submit Transaction button and sign the transaction

Staking Execute Leave Delegators Extrinsic

Once the transaction is confirmed, you can verify that your delegation was removed or that you left the set of delegators by going to the Chain state option under the Developer tab. Here, provide the following information:

  1. Choose the parachainStaking pallet
  2. Choose the delegatorState state to query
  3. Select your account
  4. Make sure to enable the include options slider
  5. Send the state query by clicking on the + button

Staking Verify Delegation is Revoked

In the response, you should see your account (in this case, Alice's account) with a list of the remaining delegations. Each delegation contains the target address of the candidate, and the amount. There should no longer be an entry for 0x623c9E50647a049F92090fe55e22cC0509872FB6. Or if you left the delegator set, you should see a response of <none>.

To ensure the revocation went through as expected, you can follow the steps in the Verifying Delegations section above.

Cancel Request to Stop Delegations

If you scheduled a request to stop delegations but changed your mind, as long as the request has not been executed, you can cancel the request at any time and all of your delegations will remain as is. If you scheduled a request via the scheduleRevokeDelegation extrinsic, you will need to call cancelDelegationRequest. On the other hand, if you scheduled a request via the scheduleRevokeDelegation extrinsic, you will need to call the cancelLeaveDelegators extrinsic. To cancel the request you can follow these steps:

  1. Select the account to cancel the scheduled request for
  2. Choose the parachainStaking pallet
  3. Choose the cancelDelegationRequest or the cancelLeaveDelegators extrinsic
  4. Enter the candidates address that corresponds to the due request you would like to cancel
  5. Click the Submit Transaction button and sign the transaction

Staking Cancel Scheduled Request to Revoke Delegation via Chain State

Staking Rewards

As candidates in the active set of collators receive rewards from block production, delegators get rewards as well. A brief overview on how the rewards are calculated can be found in the Reward Distribution section of the Staking on Moonbeam overview page.

In summary, delegators will earn rewards based on their stake of the total delegations for the collator being rewarded (including the collator's stake as well).

From the previous example, Alice was rewarded with 0.0044 tokens after two payout rounds:

Staking Reward Example

Risks

Holders of MOVR/GLMR tokens should perform careful due diligence on collators before delegating. Being listed as a collator is not an endorsement or recommendation from the Moonbeam Network, the Moonriver Network, or Moonbeam Foundation. Neither the Moonbeam Network, Moonriver Network, nor Moonbeam Foundation has vetted the list collators and assumes no responsibility with regard to the selection, performance, security, accuracy, or use of any third-party offerings. You alone are responsible for doing your own diligence to understand the applicable fees and all risks present, including actively monitoring the activity of your collators.

You agree and understand that neither the Moonbeam Network, the Moonriver Network, nor Moonbeam Foundation guarantees that you will receive staking rewards and any applicable percentage provided (i) is an estimate only and not guaranteed, (ii) may change at any time and (iii) may be more or less than the actual staking rewards you receive. The Moonbeam Foundation makes no representations as to the monetary value of any rewards at any time.

Staking MOVR/GLMR tokens is not free of risk. Staked MOVR/GLMR tokens are locked up, and retrieving them requires a 2 day/7 day waiting period . Additionally, if a collator fails to perform required functions or acts in bad faith, a portion of their total stake can be slashed (i.e. destroyed). This includes the stake of their delegators. If a collators behaves suspiciously or is too often offline, delegators can choose to unbond from them or switch to another collator. Delegators can also mitigate risk by electing to distribute their stake across multiple collators.