Skip to content

Description of Staking and Child Root Communication in Edge

William Schwab edited this page May 11, 2023 · 1 revision

This is a high-level description of staking and comms between child and root in Edge post RFC-201, written as supplementary material for the Chainsecurity audit of the Edge smart contracts commencing May 9, 2023.

Summary

In order to streamline staking for Supernets, staking as a Supernet validator has been moved from the child chain (the Supernet) to root. There are also contracts handling the registration of new Supernets on root.

In addition, while previously the validator set was managed entirely by smart contracts, now the set is largely maintained directly by the Edge client. This reduces significant overhead in modifying the validator set, and also should allow for more modularity by making it easier to use different algorithms for validator selection in the future.

Diagrams

stakin_flowchart

stake_manager_flow

Description

Initialization of a new Supernet

Each Supernet has a Supernet Manager, a contract with a minimal required interface. This contract is meant to be customized per Supernet, allowing a high level of customization for different use cases. A sample Supernet Manager has been provided (CustomSupernetManager.sol).

registerChildChain() in the StakeManger cont ract is called, taking a single address as an argument. This address is Supernet Manager contract. Stake Manager then registers the id of the Supernet in the Supernet Registry.

It is an assumption that most Supernets will want validators to be whitelisted first. In the custom implementation this is done by calling the whitelistValidators() function on the Supernet Manager. (This function takes an array of addresses, allowing the administrator to whitelist a number of validators beforehand.)

At this point, whitelisted validators may begin registering to be a part of the genesis validator set. Validators stake using the stakeFor() function in Stake Manager. The function is called with the id of the Supernet (as created in registerChildChain()) and the amount of MATIC to stake. (All Supernet staking is done in MATIC.) The stakeFor() function contains a hook calling to the Supernet Manager for the chain, allowing for customization of the staking process.

Once the genesis validator set has staked, the administrator can call the finalizeGenesis() function on the Supernet Manager. This signals to the Edge client for genesis.

A Validator Set contract is deployed on the Supernet (contracts/child/validator/ValidatorSet.sol), committing the genesis set. At this point, appointed validators can commit epochs via the commitEpoch function in the Validator Set contract. The Reward Pool contract is responsible for the distribution of rewards for performing validation duties.

Lifecycle of staking/unstaking

The stakeFor() function in the Stake Manager contract is also used for staking after genesis. This relies on the _onStake callback in the stakeFor() function. In the custom implementation of a Supernet Manager there is an example of how to send the data to the State Sender bridge in order to be bridged over to the Supernet for inclusion in the validator set.

Once the message is received on the Supernet, the Edge client will perform a system call to the Validator Set contract, updating it via the onStateReceive() function. At this point, the validator will be included in the validator set of the next epoch and can begin validating.

Withdrawal of stake is initiated on the Supernet by calling the withdraw() function on the Validator Set contract. This sends a message via the bridge to the Stake Manager which, when received, will start the cooldown period, after which the validator can remove their stake from Stake Manager by calling withdrawStake() with the Supernet id.