Expand description

§Delegated Staking Pallet

This pallet implements [sp_staking::DelegationInterface] that provides delegation functionality to delegators and agents. It is designed to be used in conjunction with [StakingInterface] and relies on Config::CoreStaking to provide primitive staking functions.

Currently, it does not expose any dispatchable calls but is written with a vision to expose them in the future such that it can be utilised by any external account, off-chain entity or xcm MultiLocation such as a parachain or a smart contract.

§Key Terminologies

  • Agent: An account who accepts delegations from other accounts and act as an agent on their behalf for staking these delegated funds. Also, sometimes referred as Delegatee.
  • Delegator: An account who delegates their funds to an agent and authorises them to use it for staking.
  • AgentLedger: A data structure that holds important information about the agent such as total delegations they have received, any slashes posted to them, etc.
  • Delegation: A data structure that stores the amount of funds delegated to an agent by a delegator.

§Goals

Direct nomination on the Staking pallet does not scale well. Nominations pools were created to address this by pooling delegator funds into one account and then staking it. This though had a very critical limitation that the funds were moved from delegator account to pool account and hence the delegator lost control over their funds for using it for other purposes such as governance. This pallet aims to solve this by extending the staking pallet to support a new primitive function: delegation of funds to an agent with the intent of staking. The agent can then stake the delegated funds to Config::CoreStaking on behalf of the delegators.

§Withdrawal Management

Agent unbonding does not regulate ordering of consequent withdrawal for delegators. This is upto the consumer of this pallet to implement in what order unbondable funds from Config::CoreStaking can be withdrawn by the delegators.

§Reward and Slashing

This pallet does not enforce any specific strategy for how rewards or slashes are applied. It is upto the agent account to decide how to apply the rewards and slashes.

This importantly allows clients of this pallet to build their own strategies for reward/slashes. For example, an agent account can choose to first slash the reward pot before slashing the delegators. Or part of the reward can go to an insurance fund that can be used to cover any potential future slashes. The goal is to eventually allow foreign MultiLocations (smart contracts or pallets on another chain) to build their own pooled staking solutions similar to NominationPools.

§Core functions

  • Allow an account to receive delegations. See Pallet::register_agent.
  • Delegate funds to an agent account. See Pallet::delegate_to_agent.
  • Release delegated funds from an agent account to the delegator. See Pallet::release_delegation.
  • Migrate a Nominator account to an agent account. See Pallet::migrate_to_agent. Explained in more detail in the Migration section.
  • Migrate unclaimed delegated funds from agent to delegator. When a nominator migrates to an agent, the funds are held in a proxy account. This function allows the delegator to claim their share of the funds from the proxy account. See Pallet::migrate_delegation.

§Lazy Slashing

One of the reasons why direct nominators on staking pallet cannot scale well is because all nominators are slashed at the same time. This is expensive and needs to be bounded operation.

This pallet implements a lazy slashing mechanism. Any slashes to the agent are posted in its AgentLedger as a pending slash. Since the actual amount is held in the multiple delegator accounts, this pallet has no way to know how to apply slash. It is the agent’s responsibility to apply slashes for each delegator, one at a time. Staking pallet ensures the pending slash never exceeds staked amount and would freeze further withdraws until all pending slashes are cleared.

The user of this pallet can apply slash using DelegationInterface::delegator_slash.

§Migration from Nominator to Agent

More details here.

§Nomination Pool vs Delegation Staking

This pallet is not a replacement for Nomination Pool but adds a new primitive in addition to staking pallet that can be used by Nomination Pool to support delegation based staking. It can be thought of as an extension to the Staking Pallet in relation to Nomination Pools. Technically, these changes could be made in one of those pallets as well but that would have meant significant refactoring and high chances of introducing a regression. With this approach, we can keep the existing pallets with minimal changes and introduce a new pallet that can be optionally used by Nomination Pool. The vision is to build this in a configurable way such that runtime can choose whether to use this pallet or not.

With that said, following is the main difference between

§Nomination Pool without delegation support
  1. transfer fund from delegator to pool account, and
  2. stake from pool account as a direct nominator.
§Nomination Pool with delegation support
  1. delegate fund from delegator to pool account, and
  2. stake from pool account as an Agent account on the staking pallet.

The difference being, in the second approach, the delegated funds will be locked in-place in user’s account enabling them to participate in use cases that allows use of held funds such as participation in governance voting.

Nomination pool still does all the heavy lifting around pool administration, reward distribution, lazy slashing and as such, is not meant to be replaced with this pallet.

§Limitations

  • Rewards can not be auto-compounded.
  • Slashes are lazy and hence there could be a period of time when an account can use funds for operations such as voting in governance even though they should be slashed.

Re-exports§

Modules§

  • The pallet module in each FRAME pallet hosts the most important items needed to construct this pallet.

Macros§

Constants§

Type Aliases§