New Upgrades to Staking and Locked Tokens

Hello Flow community!

We are at the point now where we are taking a critical look back at some of the smart contracts we wrote last year, specifically for staking and managing locked tokens. We have identified some areas where we would like to reorganize and add code to avoid excessive gas usage, improve the developer/user experience, and prepare the contracts for future upgrades when we enable more sophisticated versions of epochs and byzantine fault tolerance.

We plan on performing these deployments in the near future (within a couple of months). The designs and changes aren’t finalized yet though. We are looking for feedback on what we have included, the technical implementation, and concerns about any breaking changes the community might be affected by. Links to the relevant PRs are provided in the section titles. This post is a high level summary, the PRs contain more technical details.

This post assumes you are already familiar with staking on Flow.

We have two proposals to share today:

1. General Quality of Life upgrades to the staking contract

  • Summary:
    • There are no breaking changes to transactions that interact with the staking contract. The existing user flow and transactions will continue to work, and stakers’ tokens will not be moved or affected at all.
    • Reorganizes the code that tracks if node metadata is already claimed to avoid increasing gas usage when new nodes are registered.
    • Reorganizes getters for node metadata into a unified struct.
    • Adds a stakingEnabled field. Staking operations can only be performed when this field is set to true. This is in preparation for epochs, when the staking auction phase will be shorter than the whole epoch.
    • Decouples protocol node approval from the end of the staking auction. This is also a feature that is needed in preparation for epochs.
    • If you are using old scripts that use the old node metadata getters, such as FlowIDTableStaking.getNodeCommittedBalanceWithoutDelegators(), FlowIDTableStaking.getNodeCommittedBalanceWithDelegators(), FlowIDTableStaking.getNodeCommittedBalanceWithDelegators(), or
      NodeInfo.totalTokensStaked, the old scripts will not work, because those are removed in this upgrade. These fields and functions are replaced by derived fields in the NodeInfo struct instead. You will need to update your scripts to use these.

2. Staking Collections

  • Summary:
    • We will deploy a new contract, FlowStakingCollection, that allows users to stake with as many nodes and delegators as they want from a single account, using locked or unlocked FLOW.
    • Small access modifier updates to the LockedTokens contract in order to allow the FlowStakingCollection contract to be deployed to the same account and access some fields of LockedTokens.
    • The StakingCollection resource lives in the users main account and stores a capability to the user’s unlocked FlowToken.Vault as well as their locked account, if they have one.
    • A user can register and stake with as many nodes and delegators as they want from the single staking collection, all with a single set of transactions.
    • Flow Port will be updated with these changes, and all existing Blocto and Ledger accounts will be compatible with the changes after they run a simple set up account transaction.
    None. All existing transactions will still work, even if the account has been upgraded to use the staking collection.

If you have feedback or questions about the high-level aspects of these changes, please ask them here in the forum post. If you have more technical feedback or concerns, please comment in the corresponding PR or leave a review with comments in the code. We would love to see more PR reviews from the community so y’all can get more involved! Your feedback is incredibly valuable to us!

Thank you!