Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

StakeTable

Git Source

Inherits: Initializable, InitializedAt, OwnableUpgradeable, UUPSUpgradeable

Title: Ethereum L1 component of the Espresso Global Confirmation Layer (GCL) stake table.

All functions are marked as virtual so that future upgrades can override them.

State Variables

lightClient

Reference to the light client contract.

Currently unused but will be used for slashing therefore already included in the contract.

ILightClient public lightClient

token

The staking token contract.

ERC20 public token

validators

All validators the contract knows about.

mapping(address account => Validator validator) public validators

blsKeys

BLS keys that have been seen by the contract

to simplify the reasoning about what keys and prevent some errors due to misconfigurations of validators the contract currently marks keys as used and only allow them to be used once. This for example prevents callers from accidentally registering the same BLS key twice.

mapping(bytes32 blsKeyHash => bool used) public blsKeys

validatorExits

Validators that have exited and the time at which delegators can claim their funds.

mapping(address validator => uint256 unlocksAt) public validatorExits

delegations

Currently active delegation amounts.

mapping(address validator => mapping(address delegator => uint256 amount)) public delegations

undelegations

Delegations held in escrow that are to be unlocked at a later time.

mapping(address validator => mapping(address delegator => Undelegation)) public undelegations

exitEscrowPeriod

The time (seconds) the contract will hold funds after undelegations are requested. Must allow ample time for node to exit active validator set and slashing evidence to be submitted.

uint256 public exitEscrowPeriod

Functions

constructor

since the constructor initializes storage on this contract we disable it

storage is on the proxy contract since it calls this contract via delegatecall

Note: oz-upgrades-unsafe-allow: constructor

constructor() ;

initialize

function initialize(
    address _tokenAddress,
    address _lightClientAddress,
    uint256 _exitEscrowPeriod,
    address _timelock
) public initializer;

initializeState

Initialize the state of the contract

function initializeState(
    address _tokenAddress,
    address _lightClientAddress,
    uint256 _exitEscrowPeriod
) internal;

Parameters

NameTypeDescription
_tokenAddressaddressThe address of the staking token
_lightClientAddressaddressThe address of the light client
_exitEscrowPerioduint256The exit escrow period. Set to uint64.max to disable the exit escrow period.

getVersion

Use this to get the implementation contract version

function getVersion()
    public
    pure
    virtual
    returns (uint8 majorVersion, uint8 minorVersion, uint8 patchVersion);

Returns

NameTypeDescription
majorVersionuint8The major version of the contract
minorVersionuint8The minor version of the contract
patchVersionuint8The patch version of the contract

_authorizeUpgrade

only the timelock can authorize an upgrade

function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner;

renounceOwnership

Prevent renouncing ownership to preserve governance control.

Override renounceOwnership() to revert, preventing accidental or malicious ownership renunciation

function renounceOwnership() public virtual override onlyOwner;

_hashBlsKey

Computes a hash value of some G2 point.

function _hashBlsKey(BN254.G2Point memory blsVK) public pure returns (bytes32);

Parameters

NameTypeDescription
blsVKBN254.G2PointBLS verification key in G2

Returns

NameTypeDescription
<none>bytes32keccak256(blsVK)

ensureValidatorActive

function ensureValidatorActive(address validator) internal view;

ensureValidatorNotRegistered

function ensureValidatorNotRegistered(address validator) internal view;

ensureNewKey

function ensureNewKey(BN254.G2Point memory blsVK) internal view;

ensureNonZeroSchnorrKey

function ensureNonZeroSchnorrKey(EdOnBN254.EdOnBN254Point memory schnorrVK) internal pure;

registerValidator

Register a validator in the stake table

The function will revert if

  1. the validator is already registered
  2. the schnorr key is zero
  3. if the bls signature verification fails (this prevents rogue public-key attacks).
  4. the commission is > 100%

No validity check on schnorrVK due to gas cost of Rescue hash, UIs should perform checks where possible and alert users.

function registerValidator(
    BN254.G2Point memory blsVK,
    EdOnBN254.EdOnBN254Point memory schnorrVK,
    BN254.G1Point memory blsSig,
    uint16 commission
) external virtual;

Parameters

NameTypeDescription
blsVKBN254.G2PointThe BLS verification key
schnorrVKEdOnBN254.EdOnBN254PointThe Schnorr verification key (as the auxiliary info)
blsSigBN254.G1PointThe BLS signature that authenticates the ethereum account this function is called from
commissionuint16in % with 2 decimals, from 0.00% (value 0) to 100% (value 10_000)

deregisterValidator

Deregister a validator

function deregisterValidator() public virtual;

delegate

Delegate to a validator

function delegate(address validator, uint256 amount) public virtual;

Parameters

NameTypeDescription
validatoraddressThe validator to delegate to
amountuint256The amount to delegate

undelegate

Undelegate from a validator

function undelegate(address validator, uint256 amount) public virtual;

Parameters

NameTypeDescription
validatoraddressThe validator to undelegate from
amountuint256The amount to undelegate

claimWithdrawal

Withdraw previously delegated funds after an undelegation.

function claimWithdrawal(address validator) public virtual;

Parameters

NameTypeDescription
validatoraddressThe validator to withdraw from

claimValidatorExit

Withdraw previously delegated funds after a validator has exited

function claimValidatorExit(address validator) public virtual;

Parameters

NameTypeDescription
validatoraddressThe validator to withdraw from

updateConsensusKeys

Update the consensus keys for a validator

This function is used to update the consensus keys for a validator

This function can only be called by the validator itself when it hasn’t exited

The validator will need to give up either its old BLS key and/or old Schnorr key

The validator will need to provide a BLS signature to prove that the account owns the new BLS key

function updateConsensusKeys(
    BN254.G2Point memory newBlsVK,
    EdOnBN254.EdOnBN254Point memory newSchnorrVK,
    BN254.G1Point memory newBlsSig
) external virtual;

Parameters

NameTypeDescription
newBlsVKBN254.G2PointThe new BLS verification key
newSchnorrVKEdOnBN254.EdOnBN254PointThe new Schnorr verification key
newBlsSigBN254.G1PointThe BLS signature that the account owns the new BLS key

Events

ValidatorRegistered

A registration of a new validator.

Signals to the confirmation layer that a new validator is ready to receive delegations in the stake table contract. The confirmation layer uses this event to keep track of the validator’s keys for the stake table.

The commission is in % with 2 decimals, from 0.00% (value 0) to 100% (value 10_000).

A validator registration is only valid if the BLS and Schnorr signature are valid. The GCL must verify this and otherwise discard the validator registration when it processes the event. The contract cannot verify the validity of the registration event and delegators will be able to deposit as soon as this event is emitted. In the event that a delegator delegates to an invalid validator the delegator can withdraw the delegation again in the same way they can withdraw other delegations.

UIs should do their best to prevent invalid, or duplicate registrations.

The verification key of the BLS keypair used for consensus signing is a BN254.G2Point.

The verification key of the state signing schnorr keypair is an EdOnBN254.EdOnBN254Point.

event ValidatorRegistered(
    address indexed account,
    BN254.G2Point blsVk,
    EdOnBN254.EdOnBN254Point schnorrVk,
    uint16 commission
);

ValidatorExit

A validator initiated an exit from stake table

All funds delegated to this validator are marked for withdrawal. Users can no longer delegate to this validator. Their previously delegated funds are automatically undelegated. After exitEscrowPeriod elapsed, delegators can claim the funds delegated to the exited validator via claimValidatorExit.

The GCL removes this validator and all its delegations from the active validator set.

event ValidatorExit(address indexed validator);

Delegated

A Delegator delegated funds to a validator.

The tokens are transferred to the stake table contract.

The GCL adjusts the weight for this validator and the delegators delegation associated with it.

event Delegated(address indexed delegator, address indexed validator, uint256 amount);

Undelegated

A delegator undelegation funds from a validator.

The tokens are marked to be unlocked for withdrawal.

The GCL needs to update the stake table and adjust the weight for this validator and the delegators delegation associated with it.

event Undelegated(address indexed delegator, address indexed validator, uint256 amount);

ConsensusKeysUpdated

A validator updates their signing keys.

Similarly to registration events, the correctness cannot be fully determined by the contracts.

The confirmation layer needs to update the stake table with the new keys.

event ConsensusKeysUpdated(
    address indexed account, BN254.G2Point blsVK, EdOnBN254.EdOnBN254Point schnorrVK
);

Withdrawal

A delegator claims unlocked funds.

This event is not relevant for the GCL. The events that remove stake from the stake table are Undelegated and ValidatorExit.

event Withdrawal(address indexed account, uint256 amount);

Errors

ValidatorAlreadyRegistered

A user tries to register a validator with the same address

error ValidatorAlreadyRegistered();

ValidatorInactive

error ValidatorInactive();

ValidatorAlreadyExited

A validator has already exited.

error ValidatorAlreadyExited();

ValidatorNotExited

A validator has not exited yet.

error ValidatorNotExited();

PrematureWithdrawal

error PrematureWithdrawal();

InsufficientAllowance

error InsufficientAllowance(uint256, uint256);

InsufficientBalance

error InsufficientBalance(uint256);

NothingToWithdraw

error NothingToWithdraw();

InvalidSchnorrVK

error InvalidSchnorrVK();

BlsKeyAlreadyUsed

The BLS key has been previously registered in the contract.

error BlsKeyAlreadyUsed();

InvalidCommission

The commission value is invalid.

error InvalidCommission();

ZeroAddress

Contract dependencies initialized with zero address.

error ZeroAddress();

UndelegationAlreadyExists

An undelegation already exists for this validator and delegator.

error UndelegationAlreadyExists();

ZeroAmount

A zero amount would lead to a no-op.

error ZeroAmount();

OwnershipCannotBeRenounced

Attempted to renounce ownership which would break governance controls.

error OwnershipCannotBeRenounced();

ExitEscrowPeriodInvalid

The exit escrow period is invalid (either too short or too long)

error ExitEscrowPeriodInvalid();

Structs

Validator

Represents an Espresso validator and tracks funds currently delegated to them.

The delegatedAmount excludes funds that are currently marked for withdrawal via undelegation or validator exit.

struct Validator {
    uint256 delegatedAmount;
    ValidatorStatus status;
}

Undelegation

Tracks an undelegation from a validator.

struct Undelegation {
    uint256 amount;
    uint256 unlocksAt;
}

Enums

ValidatorStatus

The status of a validator. By default a validator is in the Unknown state. This means it has never registered. Upon registration the status will become Active and if the validator deregisters its status becomes Exited.

enum ValidatorStatus {
    Unknown,
    Active,
    Exited
}