Skip to main content

CuratedModule

CuratedModule is the core staking module contract. It stores Node Operator and validator deposit data, handles interactions with the Staking Router, and provides flows for key and operator-address management, rewards, penalties, validator balances, and validator exits. Bond operations are delegated to Accounting, while exit-related obligations are recorded by ExitPenalties.

For initial deposits and subsequent 0x02 validator top-ups, CuratedModule uses the effective allocation weights and external stake supplied by MetaRegistry. This weighted strategy moves eligible Node Operators toward their target shares instead of allocating stake through a FIFO queue.

State Variables

META_REGISTRY

IMetaRegistry public immutable META_REGISTRY

STAKING_ROUTER_ROLE

bytes32 public constant STAKING_ROUTER_ROLE = keccak256("STAKING_ROUTER_ROLE")

REPORT_GENERAL_DELAYED_PENALTY_ROLE

bytes32 public constant REPORT_GENERAL_DELAYED_PENALTY_ROLE = keccak256("REPORT_GENERAL_DELAYED_PENALTY_ROLE")

SETTLE_GENERAL_DELAYED_PENALTY_ROLE

bytes32 public constant SETTLE_GENERAL_DELAYED_PENALTY_ROLE = keccak256("SETTLE_GENERAL_DELAYED_PENALTY_ROLE")

VERIFIER_ROLE

bytes32 public constant VERIFIER_ROLE = keccak256("VERIFIER_ROLE")

REPORT_REGULAR_WITHDRAWN_VALIDATORS_ROLE

bytes32 public constant REPORT_REGULAR_WITHDRAWN_VALIDATORS_ROLE =
keccak256("REPORT_REGULAR_WITHDRAWN_VALIDATORS_ROLE")

REPORT_SLASHED_WITHDRAWN_VALIDATORS_ROLE

bytes32 public constant REPORT_SLASHED_WITHDRAWN_VALIDATORS_ROLE =
keccak256("REPORT_SLASHED_WITHDRAWN_VALIDATORS_ROLE")

CREATE_NODE_OPERATOR_ROLE

bytes32 public constant CREATE_NODE_OPERATOR_ROLE = keccak256("CREATE_NODE_OPERATOR_ROLE")

OPERATOR_ADDRESSES_ADMIN_ROLE

bytes32 public constant OPERATOR_ADDRESSES_ADMIN_ROLE = keccak256("OPERATOR_ADDRESSES_ADMIN_ROLE")

LIDO_LOCATOR

ILidoLocator public immutable LIDO_LOCATOR

STETH

IStETH public immutable STETH

PARAMETERS_REGISTRY

IParametersRegistry public immutable PARAMETERS_REGISTRY

ACCOUNTING

IAccounting public immutable ACCOUNTING

EXIT_PENALTIES

IExitPenalties public immutable EXIT_PENALTIES

FEE_DISTRIBUTOR

address public immutable FEE_DISTRIBUTOR

MODULE_TYPE

bytes32 internal immutable MODULE_TYPE

Functions

constructor

constructor(
bytes32 moduleType,
address lidoLocator,
address parametersRegistry,
address accounting,
address exitPenalties,
address metaRegistry
) BaseModule(moduleType, lidoLocator, parametersRegistry, accounting, exitPenalties);

initialize

Initialize contract from scratch. In case of a method call frontrun, the contract instance should be discarded. It is recommended to call this method in the same transaction as the deployment transaction and perform extensive deployment verification before using the contract instance.

function initialize(address admin) external override initializer;

obtainDepositData

Obtains deposit data to be used by StakingRouter to deposit to the Ethereum Deposit contract

function obtainDepositData(
uint256 depositsCount,
bytes calldata depositCalldata // solhint-disable-line no-unused-vars
)
external
returns (bytes memory publicKeys, bytes memory signatures);

Parameters

NameTypeDescription
depositsCountuint256Number of deposits to be done
depositCalldatabytesStaking module defined data encoded as bytes. IMPORTANT: depositCalldata MUST NOT modify the deposit data set of the staking module

Returns

NameTypeDescription
publicKeysbytesBatch of the concatenated public validators keys
signaturesbytesBatch of the concatenated deposit signatures for returned public keys

allocateDeposits

Validates that provided keys belong to the corresponding operators in the module and calculates deposit allocations for top-up

Reverts if any key doesn't belong to the module or data is invalid

function allocateDeposits(
uint256 maxDepositAmount,
bytes[] calldata pubkeys,
uint256[] calldata keyIndices,
uint256[] calldata operatorIds,
uint256[] calldata topUpLimits
) external returns (uint256[] memory allocations);

Parameters

NameTypeDescription
maxDepositAmountuint256Total ether amount available for top-up (must be multiple of 1 gwei)
pubkeysbytes[]List of validator public keys to top up
keyIndicesuint256[]Indices of keys within their respective operators
operatorIdsuint256[]Node operator IDs that own the keys
topUpLimitsuint256[]Maximum amount that can be deposited per key based on CL data and SR internal logic.

Returns

NameTypeDescription
allocationsuint256[]Amount to deposit to each key

notifyNodeOperatorWeightChange

Notifies the module about the weight change of a node operator.

function notifyNodeOperatorWeightChange(uint256 nodeOperatorId, uint256 oldWeight, uint256 newWeight) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
oldWeightuint256The old weight of the node operator.
newWeightuint256The new weight of the node operator.

getOperatorWeights

Returns operator weights used for operator-level allocations in the module.

Provides weights from the on-chain allocation strategy used by the module.

function getOperatorWeights(uint256[] calldata operatorIds)
external
view
returns (uint256[] memory operatorWeights);

Parameters

NameTypeDescription
operatorIdsuint256[]Node operator IDs to query.

Returns

NameTypeDescription
operatorWeightsuint256[]Weights aligned with operatorIds.

getNodeOperatorWeightAndExternalStake

Returns effective weight and external stake for a node operator.

Reverts until the module deposit info cache is fully refreshed.

function getNodeOperatorWeightAndExternalStake(uint256 nodeOperatorId)
external
view
returns (uint256 weight, uint256 externalStake);

Parameters

NameTypeDescription
nodeOperatorIduint256Node operator ID to query.

Returns

NameTypeDescription
weightuint256Effective allocation weight.
externalStakeuint256External stake amount in wei.

getDepositAllocationTargets

Returns current deposit allocation targets for all operators.

Target = totalCurrent * operatorWeight / totalWeight (in validator count). Includes operators regardless of depositable capacity for informational purposes. Actual allocation recalculates shares only across operators with usable capacity, so real per-operator amounts may differ from the targets shown here. Arrays are indexed by operator id; zero-weight operators have zero values.

function getDepositAllocationTargets()
external
view
returns (uint256[] memory currentValidators, uint256[] memory targetValidators);

Returns

NameTypeDescription
currentValidatorsuint256[]Current active validator count per operator.
targetValidatorsuint256[]Target validator count per operator.

getTopUpAllocationTargets

Returns current top-up allocation targets for all operators.

target = totalCurrent * operatorWeight / totalWeight (in wei). Includes operators regardless of top-up capacity for informational purposes. Actual allocation recalculates shares only across operators with usable capacity, so real per-operator amounts may differ from the targets shown here. Arrays are indexed by operator id; zero-weight operators have zero values.

function getTopUpAllocationTargets()
external
view
returns (uint256[] memory currentAllocations, uint256[] memory targetAllocations);

Returns

NameTypeDescription
currentAllocationsuint256[]Current operator stake in wei.
targetAllocationsuint256[]Target operator stake in wei.

getDepositsAllocation

Method to get list of operators and amount of Eth that can be topped up to operator from depositAmount

function getDepositsAllocation(uint256 maxDepositAmount)
external
view
returns (uint256 allocated, uint256[] memory operatorIds, uint256[] memory allocations);

Parameters

NameTypeDescription
maxDepositAmountuint256

createNodeOperator

Permissioned method to add a new Node Operator Should be called by *Gate.sol contracts. See PermissionlessGate.sol and VettedGate.sol for examples

function createNodeOperator(
address from,
NodeOperatorManagementProperties calldata managementProperties,
address /* referrer */
)
public
virtual
whenResumed
returns (uint256 nodeOperatorId);

Parameters

NameTypeDescription
fromaddressSender address. Initial sender address to be used as a default manager and reward addresses. Gates must pass the correct address in order to specify which address should be the owner of the Node Operator.
managementPropertiesNodeOperatorManagementPropertiesOptional. Management properties to be used for the Node Operator. managerAddress: Used as managerAddress for the Node Operator. If not passed from will be used. rewardAddress: Used as rewardAddress for the Node Operator. If not passed from will be used. extendedManagerPermissions: Flag indicating that managerAddress will be able to change rewardAddress. If set to true resetNodeOperatorManagerAddress method will be disabled
<none>address

addValidatorKeysETH

Add new keys to the existing Node Operator using ETH as a bond

Any excess msg.value will be sent to the bond and can be claimed from there. This behaviour is intentional and protects users from key upload transaction front runs rendering the user transaction invalid due to changes in the required bond amount.

function addValidatorKeysETH(
address from,
uint256 nodeOperatorId,
uint256 keysCount,
bytes calldata publicKeys,
bytes calldata signatures
) external payable whenResumed;

Parameters

NameTypeDescription
fromaddressSender address. Commonly equals to msg.sender except for the case of Node Operator creation by *Gate.sol contracts
nodeOperatorIduint256ID of the Node Operator
keysCountuint256Signing keys count
publicKeysbytesPublic keys to submit
signaturesbytesSignatures of (deposit_message_root, domain) tuples https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#signingdata

addValidatorKeysStETH

Add new keys to the existing Node Operator using stETH as a bond

function addValidatorKeysStETH(
address from,
uint256 nodeOperatorId,
uint256 keysCount,
bytes calldata publicKeys,
bytes calldata signatures,
IAccounting.PermitInput calldata permit
) external whenResumed;

Parameters

NameTypeDescription
fromaddressSender address. Commonly equals to msg.sender except for the case of Node Operator creation by *Gate.sol contracts
nodeOperatorIduint256ID of the Node Operator
keysCountuint256Signing keys count
publicKeysbytesPublic keys to submit
signaturesbytesSignatures of (deposit_message_root, domain) tuples https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#signingdata
permitIAccounting.PermitInputOptional. Permit to use stETH as bond

addValidatorKeysWstETH

Add new keys to the existing Node Operator using wstETH as a bond

function addValidatorKeysWstETH(
address from,
uint256 nodeOperatorId,
uint256 keysCount,
bytes calldata publicKeys,
bytes calldata signatures,
IAccounting.PermitInput calldata permit
) external whenResumed;

Parameters

NameTypeDescription
fromaddressSender address. Commonly equals to msg.sender except for the case of Node Operator creation by *Gate.sol contracts
nodeOperatorIduint256ID of the Node Operator
keysCountuint256Signing keys count
publicKeysbytesPublic keys to submit
signaturesbytesSignatures of (deposit_message_root, domain) tuples https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#signingdata
permitIAccounting.PermitInputOptional. Permit to use wstETH as bond

proposeNodeOperatorManagerAddressChange

Propose a new manager address for the Node Operator.

Passing address(0) clears the pending proposal without changing the current manager address.

function proposeNodeOperatorManagerAddressChange(uint256 nodeOperatorId, address proposedAddress) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
proposedAddressaddressProposed manager address, or address(0) to cancel the current proposal

confirmNodeOperatorManagerAddressChange

Confirm a new manager address for the Node Operator. Should be called from the currently proposed address

function confirmNodeOperatorManagerAddressChange(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

proposeNodeOperatorRewardAddressChange

Propose a new reward address for the Node Operator.

Passing address(0) clears the pending proposal without changing the current reward address.

function proposeNodeOperatorRewardAddressChange(uint256 nodeOperatorId, address proposedAddress) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
proposedAddressaddressProposed reward address, or address(0) to cancel the current proposal

confirmNodeOperatorRewardAddressChange

Confirm a new reward address for the Node Operator. Should be called from the currently proposed address

function confirmNodeOperatorRewardAddressChange(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

resetNodeOperatorManagerAddress

Reset the manager address to the reward address. Should be called from the reward address

function resetNodeOperatorManagerAddress(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

changeNodeOperatorRewardAddress

Change rewardAddress if extendedManagerPermissions is enabled for the Node Operator

function changeNodeOperatorRewardAddress(uint256 nodeOperatorId, address newAddress) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
newAddressaddressProposed reward address

changeNodeOperatorAddresses

Change both reward and manager addresses of a node operator. An emergency method.

Only privileged role member can call this method if the role is assigned.

function changeNodeOperatorAddresses(uint256 nodeOperatorId, address newManagerAddress, address newRewardAddress)
external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
newManagerAddressaddressNew manager address
newRewardAddressaddressNew reward address

onRewardsMinted

Called by StakingRouter to signal that stETH rewards were minted for this module.

Passes through the minted stETH shares to the fee distributor

function onRewardsMinted(uint256 totalShares) external;

Parameters

NameTypeDescription
totalSharesuint256Amount of stETH shares that were minted to reward all node operators.

updateExitedValidatorsCount

Updates the number of the validators in the EXITED state for node operator with given id

exitedValidatorsCount is not used inside the module, but SR still expects this data to be stored and returned. The method should be removed once there are no legacy modules in the Lido protocol and SR no longer calls this method.

function updateExitedValidatorsCount(bytes calldata nodeOperatorIds, bytes calldata exitedValidatorsCounts)
external;

Parameters

NameTypeDescription
nodeOperatorIdsbytesPacked array of the node operators id
exitedValidatorsCountsbytesPacked array of the new number of EXITED validators for the node operators

unsafeUpdateValidatorsCount

Unsafely updates the number of validators in the EXITED/STUCK states for node operator with given id 'unsafely' means that this method can both increase and decrease exited and stuck counters

exitedValidatorsCount is not used inside the module, but SR still expects this data to be stored and returned. The method should be removed once there are no legacy modules in the Lido protocol and SR no longer calls this method.

function unsafeUpdateValidatorsCount(uint256 nodeOperatorId, uint256 exitedValidatorsCount) external;

Parameters

NameTypeDescription
nodeOperatorIduint256
exitedValidatorsCountuint256

updateTargetValidatorsLimits

Updates the limit of the validators that can be used for deposit

function updateTargetValidatorsLimits(uint256 nodeOperatorId, uint256 targetLimitMode, uint256 targetLimit)
external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
targetLimitModeuint256Target limit mode for the Node Operator (see https://hackmd.io/@lido/BJXRTxMRp) 0 - disabled 1 - soft mode 2 - forced mode
targetLimituint256Target limit of validators

decreaseVettedSigningKeysCount

Called by StakingRouter to decrease the number of vetted keys for Node Operators with given ids

function decreaseVettedSigningKeysCount(bytes calldata nodeOperatorIds, bytes calldata vettedSigningKeysCounts)
external;

Parameters

NameTypeDescription
nodeOperatorIdsbytesBytes packed array of the Node Operator ids
vettedSigningKeysCountsbytesBytes packed array of the new numbers of vetted keys for the Node Operators

removeKeys

Remove keys for the Node Operator. Charging is module-specific (e.g., CSM applies a per-key fee). This method is a part of the Optimistic Vetting scheme. After key deletion totalVettedKeys is set equal to totalAddedKeys. If invalid keys are not removed, the unvetting process will be repeated and decreaseVettedSigningKeysCount will be called by StakingRouter.

function removeKeys(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount) external virtual;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
startIndexuint256Index of the first key
keysCountuint256Keys count to delete

updateDepositableValidatorsCount

Update depositable validators data for the given Node Operator.

The following rules are applied:

  • Unbonded keys can not be depositable
  • Unvetted keys can not be depositable
  • Depositable keys count should respect targetLimit value
function updateDepositableValidatorsCount(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

reportGeneralDelayedPenalty

Report general delayed penalty for the given Node Operator

function reportGeneralDelayedPenalty(
uint256 nodeOperatorId,
bytes32 penaltyType,
uint256 amount,
string calldata details
) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
penaltyTypebytes32Type of the penalty
amountuint256Penalty amount in ETH
detailsstringAdditional details about the penalty

cancelGeneralDelayedPenalty

Cancel previously reported and not settled general delayed penalty for the given Node Operator

function cancelGeneralDelayedPenalty(uint256 nodeOperatorId, uint256 amount) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
amountuint256Amount of penalty to cancel

settleGeneralDelayedPenalty

Settles locked bond for eligible Node Operators

SETTLE_GENERAL_DELAYED_PENALTY_ROLE role is expected to be assigned to Easy Track

function settleGeneralDelayedPenalty(uint256[] calldata nodeOperatorIds, uint256[] calldata bondLockNonces)
external;

Parameters

NameTypeDescription
nodeOperatorIdsuint256[]IDs of the Node Operators
bondLockNoncesuint256[]Bond lock nonces for each Node Operator

compensateGeneralDelayedPenalty

Compensate general delayed penalty (locked bond) for the given Node Operator from Node Operator's bond

Can only be called by the Node Operator manager

function compensateGeneralDelayedPenalty(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

reportValidatorSlashing

Report Node Operator's key as slashed.

function reportValidatorSlashing(uint256 nodeOperatorId, uint256 keyIndex) external;

Parameters

NameTypeDescription
nodeOperatorIduint256The ID of the Node Operator
keyIndexuint256Index of the key in the Node Operator's keys storage

reportValidatorBalance

Update verified on-chain balance for a key.

The function stores balance relative to MIN_ACTIVATION_BALANCE.

function reportValidatorBalance(uint256 nodeOperatorId, uint256 keyIndex, uint256 currentBalanceWei)
public
virtual;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
keyIndexuint256Index of the key in the Node Operator's keys storage
currentBalanceWeiuint256Proven current validator balance in wei

reportSlashedWithdrawnValidators

Report withdrawn validators that have been slashed.

function reportSlashedWithdrawnValidators(WithdrawnValidatorInfo[] calldata validatorInfos) external;

Parameters

NameTypeDescription
validatorInfosWithdrawnValidatorInfo[]An array of WithdrawnValidatorInfo structs

reportRegularWithdrawnValidators

Report Node Operator's keys as withdrawn and charge penalties associated with exit if any. A validator is considered withdrawn in the following cases:

  • if it's an exit of a non-slashed validator, when a withdrawal of the validator is included in a beacon block;
  • if it's an exit of a slashed validator, when the committee reports such a validator as withdrawn; note that it can happen earlier than the actual withdrawal is included on the beacon chain if the committee decides it can account for all penalties in advance;
  • if it's a consolidated validator, when the corresponding pending consolidation is processed and the balance of the validator has been moved to another validator.
function reportRegularWithdrawnValidators(WithdrawnValidatorInfo[] calldata validatorInfos) external;

Parameters

NameTypeDescription
validatorInfosWithdrawnValidatorInfo[]An array of WithdrawnValidatorInfo structs

reportValidatorExitDelay

Handles tracking and penalization logic for a validator that remains active beyond its eligible exit window.

This function is called by the StakingRouter to report the current exit-related status of a validator belonging to a specific node operator. It accepts a validator's public key, associated with the duration (in seconds) it was eligible to exit but has not exited. This data could be used to trigger penalties for the node operator if the validator has exceeded the allowed exit window.

function reportValidatorExitDelay(
uint256 nodeOperatorId,
uint256 proofSlotTimestamp, // solhint-disable-line no-unused-vars
bytes calldata publicKey,
uint256 eligibleToExitInSec
) external;

Parameters

NameTypeDescription
nodeOperatorIduint256
proofSlotTimestampuint256
publicKeybytes
eligibleToExitInSecuint256

onValidatorExitTriggered

Handles the triggerable exit event for a validator belonging to a specific node operator.

This function is called by the StakingRouter when a validator is exited using the triggerable exit request on the Execution Layer (EL).

function onValidatorExitTriggered(
uint256 nodeOperatorId,
bytes calldata publicKey,
uint256 elWithdrawalRequestFeePaid,
uint256 exitType
) external;

Parameters

NameTypeDescription
nodeOperatorIduint256
publicKeybytes
elWithdrawalRequestFeePaiduint256
exitTypeuint256

updateDepositInfo

Update deposit info for the given Node Operator.

function updateDepositInfo(uint256 nodeOperatorId) external;

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

requestFullDepositInfoUpdate

Request a full update of deposit info for all node operators. Should be called after external changes that can affect deposit info such as bond curve change or parameters update.

function requestFullDepositInfoUpdate() external;

batchDepositInfoUpdate

Request a batch update of deposit info for node operators. If requestFullDepositInfoUpdate was called before, the update will start from the first operator. Otherwise, it will continue from the next operator after the last updated one.

function batchDepositInfoUpdate(uint256 maxCount) external returns (uint256 operatorsLeft);

Parameters

NameTypeDescription
maxCountuint256Maximum number of operators to update in this batch

Returns

NameTypeDescription
operatorsLeftuint256Number of operators left to update

onExitedAndStuckValidatorsCountsUpdated

Called by StakingRouter after it finishes updating exited and stuck validators counts for this module's node operators. Guaranteed to be called after an oracle report is applied, regardless of whether any node operator in this module has actually received any updated counts as a result of the report but given that the total number of exited validators returned from getStakingModuleSummary is the same as StakingRouter expects based on the total count received from the oracle.

This method is not used in the module since rewards are distributed by a performance oracle, hence it does nothing

function onExitedAndStuckValidatorsCountsUpdated() external view;

getStakingModuleSummary

Returns all-validators summary in the staking module

function getStakingModuleSummary()
external
view
virtual
returns (uint256 totalExitedValidators, uint256 totalDepositedValidators, uint256 depositableValidatorsCount);

Returns

NameTypeDescription
totalExitedValidatorsuint256Total number of validators in the EXITED state on the Consensus Layer. This value can't decrease in normal conditions
totalDepositedValidatorsuint256Total number of validators deposited via the official Deposit Contract. This value is a cumulative counter: even when the validator goes into EXITED state this counter is not decreasing
depositableValidatorsCountuint256Number of validators in the set available for deposit

onWithdrawalCredentialsChanged

Called by StakingRouter when withdrawal credentials are changed.

Changing the WC means that the current deposit data in the queue is not valid anymore and can't be deposited. If there are depositable validators in the queue, the method should revert to prevent deposits with invalid withdrawal credentials.

function onWithdrawalCredentialsChanged() external view;

getInitializedVersion

Returns the initialized version of the contract

function getInitializedVersion() external view returns (uint64);

isValidatorSlashed

Checks if a validator was reported as slashed

function isValidatorSlashed(uint256 nodeOperatorId, uint256 keyIndex) external view returns (bool);

Parameters

NameTypeDescription
nodeOperatorIduint256The ID of the node operator
keyIndexuint256Index of the key in the Node Operator's keys storage

Returns

NameTypeDescription
<none>boolTrue if a validator was reported as slashed

isValidatorWithdrawn

Check if the given Node Operator's key is reported as withdrawn

function isValidatorWithdrawn(uint256 nodeOperatorId, uint256 keyIndex) external view returns (bool);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
keyIndexuint256Index of the key in the Node Operator's keys storage

Returns

NameTypeDescription
<none>boolIs validator reported as withdrawn or not

getType

Returns the type of the staking module

function getType() external view returns (bytes32);

Returns

NameTypeDescription
<none>bytes32Module type

getNodeOperator

Get Node Operator info

function getNodeOperator(uint256 nodeOperatorId) external view returns (NodeOperator memory);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

Returns

NameTypeDescription
<none>NodeOperatorNode Operator info

getNodeOperatorManagementProperties

Get Node Operator management properties

function getNodeOperatorManagementProperties(uint256 nodeOperatorId)
external
view
returns (NodeOperatorManagementProperties memory);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

Returns

NameTypeDescription
<none>NodeOperatorManagementPropertiesNode Operator management properties

getNodeOperatorOwner

Get Node Operator owner. Owner is manager address if extendedManagerPermissions is enabled and reward address otherwise

function getNodeOperatorOwner(uint256 nodeOperatorId) external view returns (address);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

Returns

NameTypeDescription
<none>addressNode Operator owner

getNodeOperatorNonWithdrawnKeys

Get Node Operator non-withdrawn keys

function getNodeOperatorNonWithdrawnKeys(uint256 nodeOperatorId) external view returns (uint256);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

Returns

NameTypeDescription
<none>uint256Non-withdrawn keys count

getNodeOperatorBalance

Returns tracked operator balance (active validator base stake plus tracked extra).

The tracked extra is intentionally monotonic for active validators and is reduced on withdrawal reporting, not on intermediate balance decreases, so the value serves both top-up allocation and withdrawal penalty accounting.

function getNodeOperatorBalance(uint256 nodeOperatorId) external view returns (uint256);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator

getNodeOperatorSummary

depositableValidatorsCount depends on:

  • totalVettedKeys
  • totalDepositedKeys
  • totalExitedKeys
  • targetLimitMode
  • targetValidatorsCount
  • totalUnbondedKeys
function getNodeOperatorSummary(uint256 nodeOperatorId)
external
view
returns (
uint256 targetLimitMode,
uint256 targetValidatorsCount,
uint256 stuckValidatorsCount,
uint256 refundedValidatorsCount,
uint256 stuckPenaltyEndTimestamp,
uint256 totalExitedValidators,
uint256 totalDepositedValidators,
uint256 depositableValidatorsCount
);

Parameters

NameTypeDescription
nodeOperatorIduint256id of the operator to return report for

Returns

NameTypeDescription
targetLimitModeuint256shows whether the current target limit applied to the node operator (1 = soft mode, 2 = forced mode)
targetValidatorsCountuint256relative target active validators limit for operator
stuckValidatorsCountuint256number of validators with an expired request to exit time
refundedValidatorsCountuint256number of validators that can't be withdrawn, but deposit costs were compensated to the Lido by the node operator
stuckPenaltyEndTimestampuint256time when the penalty for stuck validators stops applying to node operator rewards
totalExitedValidatorsuint256total number of validators in the EXITED state on the Consensus Layer. This value can't decrease in normal conditions
totalDepositedValidatorsuint256total number of validators deposited via the official Deposit Contract. This value is a cumulative counter: even when the validator goes into EXITED state this counter is not decreasing
depositableValidatorsCountuint256number of validators in the set available for deposit

getSigningKeys

Get Node Operator signing keys

function getSigningKeys(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount)
external
view
returns (bytes memory keys);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
startIndexuint256Index of the first key
keysCountuint256Count of keys to get

Returns

NameTypeDescription
keysbytesSigning keys

getSigningKeysWithSignatures

Get Node Operator signing keys with signatures

function getSigningKeysWithSignatures(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount)
external
view
returns (bytes memory keys, bytes memory signatures);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
startIndexuint256Index of the first key
keysCountuint256Count of keys to get

Returns

NameTypeDescription
keysbytesSigning keys
signaturesbytesSignatures of (deposit_message_root, domain) tuples https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#signingdata

getNonce

Returns a counter that MUST change its value whenever the deposit data set changes. Below is the typical list of actions that requires an update of the nonce:

  1. a node operator's deposit data is added
  2. a node operator's deposit data is removed
  3. a node operator's ready-to-deposit data size is changed
  4. a node operator was activated/deactivated
  5. a node operator's deposit data is used for the deposit Note: Depending on the StakingModule implementation above list might be extended

In some scenarios, it's allowed to update nonce without actual change of the deposit data subset, but it MUST NOT lead to the DOS of the staking module via continuous update of the nonce by the malicious actor

function getNonce() external view returns (uint256);

getNodeOperatorsCount

Returns total number of node operators

function getNodeOperatorsCount() external view returns (uint256);

getActiveNodeOperatorsCount

Returns number of active node operators

The module has no inactive Node Operator state, so active operators are all existing operators.

function getActiveNodeOperatorsCount() external view returns (uint256);

getNodeOperatorIsActive

Returns if the node operator with given id is active

The module has no inactive Node Operator state, so active means existing.

function getNodeOperatorIsActive(uint256 nodeOperatorId) external view returns (bool);

Parameters

NameTypeDescription
nodeOperatorIduint256Id of the node operator

getNodeOperatorIds

Returns up to limit node operator ids starting from the offset. The order of the returned ids is not defined and might change between calls.

This view must not revert in case of invalid data passed. When offset exceeds the total node operators count or when limit is equal to 0 MUST be returned empty array.

function getNodeOperatorIds(uint256 offset, uint256 limit)
external
view
returns (uint256[] memory nodeOperatorIds);

isValidatorExitDelayPenaltyApplicable

Determines whether a validator's exit status should be updated and will have an effect on the Node Operator.

function isValidatorExitDelayPenaltyApplicable(
uint256 nodeOperatorId,
uint256 proofSlotTimestamp, // solhint-disable-line no-unused-vars
bytes calldata publicKey,
uint256 eligibleToExitInSec
) external view returns (bool);

Parameters

NameTypeDescription
nodeOperatorIduint256
proofSlotTimestampuint256
publicKeybytes
eligibleToExitInSecuint256

Returns

NameTypeDescription
<none>boolReturns true if the contract should receive the updated status of the validator.

exitDeadlineThreshold

Returns the number of seconds after which a validator is considered late.

function exitDeadlineThreshold(uint256 nodeOperatorId) external view returns (uint256);

Parameters

NameTypeDescription
nodeOperatorIduint256

Returns

NameTypeDescription
<none>uint256The exit deadline threshold in seconds.

getKeyAllocatedBalances

Get cumulative top-up amounts allocated to Node Operator keys (above MIN_ACTIVATION_BALANCE)

function getKeyAllocatedBalances(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount)
external
view
returns (uint256[] memory balances);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
startIndexuint256Index of the first key
keysCountuint256Count of keys to get

Returns

NameTypeDescription
balancesuint256[]Allocated balances above MIN_ACTIVATION_BALANCE (wei)

getKeyConfirmedBalances

Get verifier-confirmed balances for Node Operator keys (above MIN_ACTIVATION_BALANCE)

function getKeyConfirmedBalances(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount)
external
view
returns (uint256[] memory balances);

Parameters

NameTypeDescription
nodeOperatorIduint256ID of the Node Operator
startIndexuint256Index of the first key
keysCountuint256Count of keys to get

Returns

NameTypeDescription
balancesuint256[]Confirmed balances above MIN_ACTIVATION_BALANCE (wei)

getTotalModuleStake

Returns the total tracked stake of the module in wei.

This is the sum of the activation base for active validators and tracked extra stake. The tracked extra is intentionally reduced on withdrawal reporting rather than on intermediate validator balance decreases.

function getTotalModuleStake() public view override returns (uint256);

getNodeOperatorDepositInfoToUpdateCount

Get the number of Node Operators with outdated deposit info that requires update.

function getNodeOperatorDepositInfoToUpdateCount() external view returns (uint256 count);

_updateDepositInfo

function _updateDepositInfo(uint256 nodeOperatorId) internal override;

_applyDepositableValidatorsCount

function _applyDepositableValidatorsCount(
NodeOperator storage no,
uint256 nodeOperatorId,
uint256 newCount,
bool incrementNonceIfUpdated
) internal override returns (bool depositableChanged);

_allocateTopUps

function _allocateTopUps(
uint256 maxDepositAmount,
uint256[] calldata operatorIds,
uint256[] calldata keyIndices,
uint256[] memory topUpLimits
) internal returns (uint256[] memory allocations);

_validateTopUpPublicKeys

function _validateTopUpPublicKeys(
bytes[] calldata pubkeys,
uint256[] calldata keyIndices,
uint256[] calldata operatorIds
) internal view;

_metaRegistry

function _metaRegistry() internal view returns (IMetaRegistry);

_canRequestDepositInfoUpdate

function _canRequestDepositInfoUpdate() internal view override;

__BaseModule_init

function __BaseModule_init(address admin) internal onlyInitializing;

_reportWithdrawnValidators

function _reportWithdrawnValidators(WithdrawnValidatorInfo[] calldata validatorInfos, bool slashed) internal;

_incrementModuleNonce

function _incrementModuleNonce() internal;

_addKeysAndUpdateDepositableValidatorsCount

function _addKeysAndUpdateDepositableValidatorsCount(
uint256 nodeOperatorId,
uint256 keysCount,
bytes calldata publicKeys,
bytes calldata signatures
) internal virtual;

_updateDepositableValidatorsCount

function _updateDepositableValidatorsCount(uint256 nodeOperatorId, bool incrementNonceIfUpdated)
internal
returns (bool changed);

_removeKeys

function _removeKeys(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount, bool useKeyRemovalCharge)
internal
virtual;

_checkCanAddKeys

function _checkCanAddKeys(uint256 nodeOperatorId, address who) internal view virtual;

_onlyNodeOperatorManager

function _onlyNodeOperatorManager(uint256 nodeOperatorId, address from) internal view;

_nodeOperatorExists

function _nodeOperatorExists(uint256 nodeOperatorId) internal view returns (bool);

_onlyExistingNodeOperator

function _onlyExistingNodeOperator(uint256 nodeOperatorId) internal view;

_onlyValidIndexRange

NOTE: The function does not revert when startIndex is equal to totalAddedKeys and keysCount is zero. The method might be fixed later once we're sure all off-chain tooling will handle the updated behaviour.

function _onlyValidIndexRange(uint256 nodeOperatorId, uint256 startIndex, uint256 keysCount) internal view;

_onlyValidKeyIndex

function _onlyValidKeyIndex(uint256 nodeOperatorId, uint256 keyIndex) internal view;

_getBondCurveId

function _getBondCurveId(uint256 nodeOperatorId) internal view returns (uint256);

_getRequiredBondForNextKeys

function _getRequiredBondForNextKeys(IAccounting accounting, uint256 nodeOperatorId, uint256 keysCount)
internal
view
returns (uint256 amount);

_checkStakingRouterRole

function _checkStakingRouterRole() internal view;

_checkReportGeneralDelayedPenaltyRole

function _checkReportGeneralDelayedPenaltyRole() internal view;

_checkVerifierRole

function _checkVerifierRole() internal view;

_checkCreateNodeOperatorRole

function _checkCreateNodeOperatorRole() internal view;

_accounting

This function is used to get the accounting contract from immutables to save bytecode.

function _accounting() internal view returns (IAccounting);

_exitPenalties

This function is used to get the exit penalties contract from immutables to save bytecode.

function _exitPenalties() internal view returns (IExitPenalties);

_parametersRegistry

This function is used to get the parameters registry contract from immutables to save bytecode.

function _parametersRegistry() internal view returns (IParametersRegistry);

_requireDepositInfoUpToDate

function _requireDepositInfoUpToDate() internal view;

_onlyRecoverer

function _onlyRecoverer() internal view override;

__checkRole

function __checkRole(bytes32 role) internal view override;