How to Stake your Tokens¶
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 where 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 deprecatedleaveNominators
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
executeCandidateBondRequest
extrinsic. Replaces the deprecatednominatorBondLess
extrinsic - executeCandidateBondRequest(address candidate) - extrinsic to execute a decrease in the bond for a specific candidate. 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 deprecatedrevokeNomination
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
- 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:
- Select the Constants tab on the Chain state UI
- From the selected constant query dropdown, choose parachainStaking
- 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
- Click + to return the current value
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:
- Head to the Developer tab
- Click on Chain State
- Choose the pallet to interact with. In this case, it is the parachainStaking pallet
- Choose the state to query. In this case, it is the selectedCandidates or candidatePool state
- 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 80 candidates
- candidatePool — returns the current list of all the candidates, including those that are not in the active set
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:
- Choose the parachainStaking pallet to interact with
- Choose the candidateInfo state to query
- Make sure the include option slider is enabled
- Enter the collator candidate's address
- Send the state query by clicking on the + button
- Copy the result as you'll need it when initiating a delegation
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);
- Head to the Developer tab
- Click on JavaScript
- Copy the code from the previous snippet and paste it inside the code editor box
- (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
- To execute the code, click on the run button
- Copy the result as you'll need it when initiating a delegation
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 this 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:
To delegate a candidate, provide the following information:
- Select the account from which you want to stake your tokens
- Choose the parachainStaking pallet
- Choose the delegate extrinsic
- Set the candidate's address to delegate. In this case, it is set to
0x4c5A56ed5A4FF7B09aA86560AfD7d383F4831Cce
- Set the number of tokens you want to stake
- Input the
candidateDelegationCount
you retrieved previously from queryingcandidateInfo
- Input the
delegationCount
you retrieved from the JavaScript console. This is0
if you haven't yet delegated a candidate - Click the Submit Transaction button and sign the transaction
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.
Once the transaction is confirmed, you can head back to the Accounts tab to verify that you have a reserved balance (equal to the number of tokens staked).
To verify a delegation, you can navigate to Chain state under the Developer tab.
Here, provide the following information:
- Choose the pallet you want to interact with. In this case, it is the parachainStaking pallet
- Choose the state to query. In this case, it is the delegatorState
- Verify the selected address is correct. In this case, we are looking at Alice's account
- Make sure to enable the include option slider
- Send the state query by clicking on the + button
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:
- Select the account from which you want to remove your delegation
- Choose the
parachainStaking
pallet - Choose the
scheduleRevokeDelegation
extrinsic - Set the candidate's address you want to remove your delegation from. In this case, it is set to
0x623c9E50647a049F92090fe55e22cC0509872FB6
- Click the Submit Transaction button and sign the transaction
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.
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:
- Select the account to execute the revocation
- Choose the parachainStaking pallet
- Choose the executeDelegationRequest extrinsic
- Set the delegator's address you want to remove the delegation for. For this example, it will be Alice's address
0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac
- Set the candidate's address you want to remove your delegation from. In this case, it is set to
0x623c9E50647a049F92090fe55e22cC0509872FB6
- Click the Submit Transaction button and sign the transaction
If you want to remove all ongoing delegations, you can adapt the Extrinsics instructions to call the executeLeaveDelegators
extrinsic:
- Select the account to remove all the delegations for
- Choose the parachainStaking pallet
- Choose the executeLeaveDelegators extrinsic
- Enter the total number of all delegations to revoke using the
delegationCount
you retrieved from the JavaScript console. This is0
if you haven't yet delegated a candidate - Click the Submit Transaction button and sign the transaction
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:
- Choose the parachainStaking pallet
- Choose the delegatorState state to query
- Select your account
- Make sure to enable the include options slider
- Send the state query by clicking on the + button
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>
.
You can also check your free and reserved balances from the Accounts tab and notice now that the execution has gone through, your balances have been updated.
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:
- Select the account to cancel the scheduled request for
- Choose the parachainStaking pallet
- Choose the cancelDelegationRequest or the cancelLeaveDelegators extrinsic
- Enter the candidates address that corresponds to the due request you would like to cancel
- Click the Submit Transaction button and sign the transaction
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 this 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:
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.