Technical Overview of the Flow Staking Auction Phase
This document describes the functionality of the core identity table and staking smart contract. It gives an overview of the process of epochs, staking as a node, and delegation. It is an important prerequisite to understand before proceeding with any other technical integration or interaction with the Flow Protocol, but does not provide step-by-step instructions for how to perform specific actions. See the Staking Collection Docs for instructions
This document also describes how to read public staking data from the contract. Anyone can read public data from the staking smart contract with these instructions.
The transactions described in this document are contained in the
directory. You can see the text of all the transactions used to interact with the smart contract there.
The Flow staking smart contract manages a record of stakers who have staked tokens for the network. Users who want to stake can register with the staking contract at any time, and their tokens will be locked for staking until they request to unstake them.
You should already understand from reading the epoch documentation
that an epoch lasts roughly a week. The
FlowIDTableStaking contract focuses on the identity table
and staking part of the epoch schedule.
Epoch Schedule from the perspective of the
- Start of Epoch: Generic metadata about the current epoch is updated and shared and the staking auction is enabled.
- Staking Auction: Stakers can perform any action they want to manage their stake, like initially registering, staking new tokens, unstaking tokens, or withdrawing rewards. This phase takes up the vast majority of time in the epoch.
- End Staking Auction: Stakers cannot perform any more staking actions until the start of the next epoch/staking auction.
- Remove Insufficiently Staked Nodes: All node operators who don't meet the minimum or are not operating their node properly will be removed.
- Rewards Calculation: Calculate rewards for all the node operators staked in the current epoch.
- Move tokens between pools. (See the token pools section for the order of movements)
- Rewards Payout: Pay rewards to all the node operators staked from the previous epoch using the calculation from earlier in the epoch.
- End Epoch: Set the reward payout for the upcoming epoch and go to the top of this list.
FlowIDTableStaking contract manages the identity table, and all of these phases.
Initially, control of these phases is controlled by the
object stored in the Flow Epoch account storage.
Control will eventually be completely decentralized and managed by the node software, smart contracts,
and democratically by all the stakers in the network.
For a node to stake, node operators first need to generate their staking key, networking address, and networking key.
The node operation guide describes how to run a node and generate node information.
To generate a node ID, simply hash the staking key.
Node operators need to determine the role of node they will be running (Collection, Consensus, Execution, Verification, or Access).
Once the info has been determined:
- Node role:
UInt8(1 = Collection, 2 = Consensus, 3 = Execution, 4 = Verification, 5 = Access)
- Node ID: 32 byte
String(64 hex characters)
- Networking Address:
String(Length must be less than 510 characters and be a properly formatted IP address or hostname)
- Networking Key: 64 byte
String(128 hex characters, must be a valid ECDSA-P256 Key)
- Staking Key: 96 byte
String(192 hex characters, must be a valid BLS key)
The node operator is ready to register their node.
To register a node, the node operator calls the
on the staking contract, providing all the node info and the tokens that they want to immediately stake, if any.
This registers the node in the Flow node identity table and commits the specified tokens to stake during the next epoch. This also returns a special node operator object that is stored in the node operator's account. This object is used for staking, unstaking, and withdrawing rewards.
Every node operator will run the same transaction to register their node at any time throughout the staking auction.
Once node operators have registered and have the special node object, they will be able to perform any of the valid staking options with it, assuming that they have the required amount of tokens to perform each operation.
When the staking auction ends, if a node operator has committed less than the minimum stake required, or if their node information is invalid and they haven't been approved by the network, their committed tokens are moved to their unstaked pool, which they can withdraw from at any time.
Nodes who did have enough tokens committed and are approved will have their committed tokens moved to the staked state at the end of the epoch.
If a node operator has users delegating to them, they cannot withdraw their own tokens such that their own staked tokens would fall below the minimum requirement for that node type. If they have delegators and try to submit an unstaking transaction that would put their stake below the minimum, it will fail.
If they want to unstake below the minimum, they must unstake all of their tokens using the special
which also unstakes all of the tokens that have been delegated to them.
Consequently, a node operator cannot accept delegation unless their own stake is above the minimum.
Every staked node in the Flow network is eligible for delegation by any other user. The user only needs to know the node ID of the node they want to delegate to.
To register as a delegator, the delegator submits a Register Delegator
transaction that calls the
providing the ID of the node operator they want to delegate to.
This transaction should store the
in the user's account, which is what they use to perform staking operations.
Users are able to get a list of possible node IDs to delegate to via on-chain scripts. This information will also be provided off-chain, directly from the node operators or via third-party services. The Flow team lists available node IDs in a public repo.
The fee that node operators take from the rewards their delegators receive is 8%. A node operator cannot be delegated to unless the total tokens they have committed to stake are above the minimum requirement for their node types.
The delegation logic keeps track of the amount of tokens each delegator has delegated for the node operator. When rewards are paid, the protocol automatically takes the 8% cut of the delegator's rewards for the node operator and the delegator's rewards are deposited in the delegator's reward pool.
Regardless of whether they are a node operator or delegator, a staker has access to all the same staking operations, outlined below. Specific implementations of these transactions are detailed in the Staking Collection Docs
A staker can commit more tokens to stake for the next epoch at any time during the staking auction, and there are three different ways to do it.
- They can commit new tokens to stake by submitting a stake_new_tokens transaction, which withdraws tokens from their account's flow token vault and commits them.
- They can commit tokens that are in their unstaked token pool, which holds the tokens that they have unstaked. Submit a stake_unstaked_tokens transaction to move the tokens from the unstaked pool to the committed pool.
- They can commit tokens that are in their rewarded token pool, which holds the tokens they have been awarded. They submit a stake_rewarded_tokens transaction to move the tokens from the rewards pool to the committed pool.
At any time during the staking auction, a staker can submit a request to unstake tokens with a request_unstaking transaction. If there are tokens that have been committed but are not staked yet, they are moved to the unstaked pool and are available to withdraw.
If the requested tokens are in the staked pool, it marks the specified amount of tokens to be unstaked at the end of the epoch. At the end of the epoch, the tokens are moved to the unstaking pool. They will sit in this pool for one (1) additional epoch, at which point they will be moved to the unstaked tokens pool.
Unstaking requests are not fulfilled until the end of the epoch where they are submitted, so a staker can cancel the unstaking request before it is carried out. A staker can do this by submitting a stake_unstaked_tokens transaction, specifying the number of tokens of their unstake request they would like to cancel. If the specified number of tokens have been requested to unstake, the request will be canceled.
At any time, stakers are able to freely withdraw from their unstaked tokens pool with the withdraw_unstaked transaction.
Staking rewards are paid out at the end of every epoch based on how many tokens
are in a users
tokensStaked pool. Every staker's rewards
are deposited into their rewarded tokens pool. Rewards can be withdrawn
at any time by submitting a withdraw_reward_tokens transaction.
These tokens are unlocked and can be transferred on-chain if desired, or re-staked.
The source code for the staking contract and more transactions can be found in the Flow Core Contracts GitHub Repository.
See the staking events document for information about the events that can be emitted by the staking contract.
Each node operator has five token pools allocated to them:
- Committed Tokens: Tokens that are committed for the next epoch. They are automatically moved to the staked pool when the next epoch starts.
- Staked Tokens: Tokens that are staked by the node operator for the current epoch. They are only moved at the end of an epoch and if the staker has submitted an unstaking request.
- Unstaking Tokens: Tokens that have been unstaked, but are not free to withdraw until the following epoch.
- Unstaked Tokens: Tokens that are freely available to withdraw or re-stake. Unstaked tokens go to this pool.
- Rewarded Tokens: Tokens that are freely available to withdraw or re-stake. Rewards are paid and deposited to the rewarded Pool after each epoch.
At the end of every epoch, tokens are moved between pools in this order:
- All committed tokens will get moved either to the staked tokens pool, or to the unstaked tokens pool (depending on if the registered node has met the minimum stake requirements).
- All committed tokens get moved to staked tokens pool.
- All unstaking tokens get moved to the unstaked tokens pool.
- All requested unstaking tokens get moved from the staked pool to the unstaking pool.