Token Delegation
Overview
To learn more about what validation and delegation are, please see the Validation docs and validation FAQ. The current page will describe the mechanics of participating in delegation.
At a high level, anyone can delegate their tokens to a staking pool which is run by a validator. This is usually just called "Staking". This is possible even if your tokens are in a lockup contract (as most tokens are during the network's early release). Delegating to a staking pool allows you to receive some staking rewards (which will activate as part of the Phase II rollout and depend on the exact fees charged by the validator) and to participate in protocol governance by adding weight to the vote of the validator whose pool you have delegated to.
You can participate in delegation by using a website (GUI), using the view
and call
methods of the command-line interface (CLI) or via sending RPC calls directly. These are described below.
Reminder: If you haven't already, evaluate your token custody options from this documentation page.
Viewing and Choosing Validators
During early days, the staking pool contracts (code) allow validators to select what fee they will charge on rewards earned by pools they run. In the future, updated versions of the staking pool contracts may include more parameters (which is one of the nice features enabled by NEAR's contract-based delegation).
Several community-run lists of validators list who they are, how much stake they have, what their vote was for the Phase II transition and more. These can be helpful for selecting where to delegate your tokens. As always, do your own diligence.
Operator | URL (to copy and paste) |
---|---|
NEAR Explorer | |
DokiaCapital | |
Stardust NEAR Pool | |
YOUR OPERATOR | ADD YOUR LINK HERE |
GUI-based delegation (via a website or app)
Disclaimer: the list below is community-maintained, and is not an endorsement by NEAR to use any of them. Do your own research before staking your funds with them!
Provider | URL (to copy and paste) | Added on |
---|---|---|
NEAR Wallet | Oct 11 2020 | |
DokiaCapital | Sept 11 2020 | |
Moonlet Wallet | 15 Oct 2020 | |
add here | your link | first come, first serve |
CLI-based delegation
Disclaimer: the documentation below refers to the Github repository Core Contracts. Always check the source of the smart contract before delegating your funds to it!
You can use near-cli
with NEAR Core Contracts to delegation via:
Lockup Contract
Staking Pool
Before starting, make sure you are running the latest version of near-cli, you are familiar with gas fees and you are sending transactions to the correct NEAR network. By default near-cli
is configured to work with TestNet. You can change the network to MainNet by issuing the command
It will also be helpful to set some variables, which we will use in commands below. On Linux/macOS/Unix:
If you're using Windows, you can replace all the export
commands with set
:
You can check that you set these correctly with echo
:
Note that when you set variables with export
you do not prefix them with the dollar sign, but when you use them elsewhere such as with echo
, you need the dollar sign.
If you're using a secondary account on a Ledger Nano device, you will also want to create an HD_PATH variable. For example:
The default HD path for the NEAR app on Ledger devices is 44'/397'/0'/0'/1'
. See more info on using near-cli
with Ledger here.
Heads up
Signing a transaction with the wrong Ledger key can help associating multiple accounts of a user, since even failed transactions are recorded to the blockchain and can be subsequently analyzed.
1. Lockup Contracts Delegation
The Lockup Contract is common among NEAR contributors and, essentially, anyone who didn't acquire tokens through an exchange. This contract acts as an escrow that locks and holds an owner's tokens for a lockup period (such as vesting). You can learn more about lockups and their implementation in the this documentation page.
The owner may want to stake these tokens (including locked ones) to help secure the network and also earn staking rewards that are distributed to the validator. The lockup contract doesn't allow to directly stake from its account, so the owner delegates the tokens using the contract built-in functions.
heads up
The commands below are tested with build 877e2db of the Core Contracts.
They also use formatting only available on Linux/macOS/Unix. If you are using Windows, you will need to replace dollar variables,
$LOCKUP_ID
, with percent variables,%LOCKUP_ID%
. And you will need to use all double quotes, so things like'{"account_id": "'$ACCOUNT_ID'"}'
become"{\"account_id\": \"%ACCOUNT_ID%\"}\"
.
Before proceeding with the tutorial below, check that you have control of your lockup contract, by issuing the command
You should expect a result like:
Note that this example us using NEAR_ENV=testnet
with $LOCKUP_ID
set to meerkat.stakewars.testnet
and ACCOUNT_ID
set to meerkat.testnet
, which matches the returned result above.
You can stake with Lockup contracts in three steps:
Set up the staking pool
Deposit and stake the tokens
Measure the rewards
a. Set the staking pool
Lockup contracts can stake to one staking pool at a time, so this parameter can be changed only while no funds are staked.
You can select the staking pool by calling the method select_staking_pool
from the lockup contract:
If using a Ledger:
You should expect a result like:
The true
statement means that your call was successful, and the lockup contract accepted the $POOL_ID
parameter.
b. Deposit and stake the tokens
Lockup contracts can stake their balance, regardless of their vesting schedule. You can proceed in two steps:
check the lockup balance
stake the balance
To know how many tokens you can stake, use the view method
get_balance
:
You should expect a result like:
Where the resulting balance (in yoctoNEAR) is 100000499656128234500000000
or 100 $NEAR.
heads up
You have to leave 35 $NEAR in the lockup contract for the storage fees. If you have 100 tokens, you can stake up to 65 tokens. If you have 1000 tokens, you can stake up to 965 tokens.
You may want to
npm i -g near-units
to easily convert yoctoNEAR amounts to human-readable representations, and to go from human-typeable numbers to yoctoNEAR. Examples:On Linux/macOS/Unix, you can also use this directly in the following commands:
You may want to set your desired amount-to-stake to a variable:
To stake the balance, use the call method deposit_and_stake
:
If using a Ledger:
Heads up
This sets the gas parameter to 200000000000000 gas units, or 200 Tgas (Teragas), as the near-cli default allocation of 30Tgas is too low.
You should expect a result like:
The true
statement at the end means the transaction was successful.
c. Measure the rewards
Since NEAR automatically re-stakes all staking pool rewards, you have to update your staked balance to know the amount of tokens you earned with your validator.
Use the call method refresh_staking_pool_balance
to check your new balance:
If using a Ledger:
You should expect a result like:
Note that in this example, the result is piped to grep (| grep "current total balance"
) to display only the relevant output.
Please refer to the Lockup Contract readme if you need to know how to withdraw the staking rewards to your main wallet.
Unstake and withdraw your lockup tokens
NEAR Protocol automatically re-stakes all the rewards back to the staking pools, so your staked balance increases over time, accruing rewards.
Before starting, it's highly recommended to read the Lockup contracts documentation to understand which portion of the tokens is liquid, and which one is still locked even after the three epochs.
If you want to withdraw funds, you have to issue two separate commands:
Manually unstake tokens from the staking pool, and wait three epochs
Manually withdraw tokens back to your main account
Both these command require the amount in yoctoNEAR, which is the smallest unit of account for NEAR tokens. You can use the table below for the conversion, or install near-units (npm i -g near-units
) and use commands like near-units 1,000N
:
NEAR | YoctoNEAR | YoctoNEAR |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
As an example, if you want to unstake 10
NEAR tokens from the staking pool, you have to call the method unstake
with 10000000000000000000000000
(1*10^24
, 10 power 24, or 10 with 24 zeros) as an argument.
a. Unstake the tokens
Before unstaking any tokens, use the the view method get_account
introduced above to know what is the available balance:
You should expect a result like:
The result of this method shows:
An unstaked balance of
5
yoctoA staked balance of
86236099167204810592552675
yocto, or86.23
$NEARcan_withdraw
isfalse
(see below)
Check your rewards
From the examples above, the initial stake of 65 NEAR tokens increased to 86.23 tokens, with 21.23 tokens as a reward!
You can unstake an amount of funds that is equal or lower than your staked_balance
, by calling the metod unstake
. You may first want to set the amount you want to unstake to a variable AMOUNT
:
Check that it looks correct:
And maybe also using near-units
:
And now unstake:
Or with a Ledger:
You should expect a result like:
The true
statement at the end means the transaction was successful.
Wait three epochs, or ~36 hours before using the withdraw command
For security reasons, NEAR Protocol keeps your unstaked funds locked for three more epochs (~36 hours). Use again the view method get_account
to verify if can_withdraw
is true
:
The result should be as follows:
Note that the variable can_withdraw
is true
. This means that the unstaked_balance
of 42000000000000000000000000
yoctoNEAR (42 NEAR tokens) is now available for withdraw.
b. Withdraw the tokens
Funds can be withdrawn after three epochs (~36 hours) from the unstake
command. It is highly recommended to read the Lockup contracts documentation to understand which portion of the unstaked tokens is available for transfers, and which is still vesting and unavailable (even after three epochs).
Use the call method withdraw_all_from_staking_pool
:
Or if using a Ledger:
You should expect a result like this one:
The true
statement confirms the successful withdrawal.
By using again the view method:
The result should be as follows:
At this point the unstaked_balance
is 0
, and the funds are back in the lockup contract balance.
Heads up
Lockup contracts allow you to transfer only the unlocked portion of your funds. In the example above, out of the 42 NEAR unstaked, only 21.23 can be transferred to another wallet or exchange.
c. Change staking pools
To change from one staking pool to another, you must first withdraw all deposits in the currently selected staking pool. Then call unselect_staking_pool
as follows (docs):
Or if using Ledger:
Staking Pool Delegation
Any funds that are not stored inside lockup contracts can be directly delegated to a staking pool by using the call method deposit_and_stake
:
Or if using Ledger:
You should expect a result like:
The empty string at the end, ''
, means the call was successful.
If you want to check your staking rewards, use the view method get_account
:
You should expect a result like:
The staked balance in this example is 100663740438210643632989745
, or 100.66
$NEAR (reminder: you can easily convert these using near-units -h 100663740438210643632989745yN
).
A pool's rewards only compound if it has been "pinged", which means either having a direct action performed on it (like someone delegating or undelegating) or if the ping
method is called on it once within a particular epoch. This is important to do if you run a pool and want your delegators to see updated reward balances.
Use the call method ping
to re-calculate the rewards up to the previous epoch:
Or if using a Ledger:
You should expect a result like:
The ''
result means that your call was successful, and the get_account
view method will provide updated results.
Note that you can ping any pool, not just one you own.
Additional links
Fun Facts
ping
ing a pool technically removes 2 epochs of future compounding but it's an extremely small amount -- without considering compounding effect of epochs with 9 hour epochs, the reward per epoch is 5% / (365 * 24 / 9) + 1 or 1.00005136986It means this reward on top of reward is what you’re losing, so that's about 1.00000000264 or 0.000000264%... meaning for 10M stake it’s 0.02638862826 NEAR per epoch.
Got a question?
Ask it on StackOverflow!
Last updated