L2 Epoch Rewards
Introduction to Celo epoch rewards on Celo as an L2.
Epoch Rewards are similar to the familiar notion of block rewards in other blockchains, minting and distributing new units of CELO as blocks are produced, to create several kinds of incentives.
In the L2 "epoch blocks” no longer exist. There are no transactions triggered by the blockchain itself. Precompiles that were used to query epoch state are also no longer available.
The concept for epochs still remains, but they are determined to be at least as long as "epoch duration” (targeted to be set as one day on mainnet), but there's no guaranteed limit of the maximal duration. The size of an epoch can no longer be deterministically calculated based on block numbers alone.
The logic for processing epochs is now fully implemented in Solidity in the EpochManager contract introduced in Contract Release 12.
Epochs are now processed using multiple calls, as the gas consumption of the process involved uses is relatively high.
Celo is no longer minted when processing the epoch, it is now transferred from the CeloUnreleasedTreasury
. The contract CeloUnreleasedTreasury
was allocated the full amount of unminted Celo at the time of the transition to L2.
When "epoch duration" has elapsed since the current epoch started, the function startNextEpochProcess
can be called. This function:
-
Is permissionless, every EOA or contract can call it given that certain conditions are met:
- Enough time has elapsed after the beginning of the epoch.
- The epoch is not currently processing.
-
Updates target voting yield
-
Calculates epoch rewards (
EpochRewards.calculateTargetEpochRewards()
) -
Allocates validator rewards:
- mints CELO and exchanges it to cUSD
- Sets an internal mapping with the allocation for each validator. Validators can later claim it calling
sendValidatorPayment
-
Starts a block that prevents certain actions to be performed, notable lock Celo, unlock Celo and change validator locks.
-
Emits events:
- EpochRewards:
TargetVotingYieldUpdated(uint256 fraction)
- CeloUnreleasedTreasury:
Released(address indexed to, uint256 amount)
- cUSD:
Transfer(address indexed from, address indexed to, uint256 value)
- EpochManager:
EpochProcessingStarted(uint256 indexed epochNumber)
- EpochRewards:
After startNextEpochProcess
is called, the epoch can be fully finished by calling finishNextEpochProcess
. This function:
-
Is permissionless, every EOA or contract can call it given that certain conditions are met:
- startNextEpochProcess has been called before.
-
Distributes rewards to voters (Celo)
-
Elects validators (the result is stored as an array of accounts of the elected validators, signers are also stored for backwards compatibility purposes)
-
Unblocks all actions blocked in
startNextEpochProcess
. -
Updates the Epoch state.
-
Emits events:
- Election:
EpochRewardsDistributedToVoters(address indexed group, uint256 value)
- CeloUnreleasedTreasury:
Released(address indexed to, uint256 amount)
- EpochManager:
EpochProcessingEnded(uint256 indexed epochNumber)
- Election: