Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"lib/eigenlayer-middleware/src/OperatorStateRetriever.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol";
import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol";
import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol";
import {IIndexRegistry} from "./interfaces/IIndexRegistry.sol";
import {BitmapUtils} from "./libraries/BitmapUtils.sol";
/**
* @title OperatorStateRetriever with view functions that allow to retrieve the state of an AVSs registry system.
* @author Layr Labs Inc.
*/
contract OperatorStateRetriever {
struct Operator {
address operator;
bytes32 operatorId;
uint96 stake;
}
struct CheckSignaturesIndices {
uint32[] nonSignerQuorumBitmapIndices;
uint32[] quorumApkIndices;
uint32[] totalStakeIndices;
uint32[][] nonSignerStakeIndices; // nonSignerStakeIndices[quorumNumberIndex][nonSignerIndex]
}
error OperatorNotRegistered();
/**
* @notice This function is intended to to be called by AVS operators every time a new task is created (i.e.)
* the AVS coordinator makes a request to AVS operators. Since all of the crucial information is kept onchain,
* operators don't need to run indexers to fetch the data.
* @param registryCoordinator is the registry coordinator to fetch the AVS registry information from
* @param operatorId the id of the operator to fetch the quorums lists
* @param blockNumber is the block number to get the operator state for
* @return 1) the quorumBitmap of the operator at the given blockNumber
* 2) 2d array of Operator structs. For each quorum the provided operator
* was a part of at `blockNumber`, an ordered list of operators.
*/
function getOperatorState(
ISlashingRegistryCoordinator registryCoordinator,
bytes32 operatorId,
uint32 blockNumber
) external view returns (uint256, Operator[][] memory) {
bytes32[] memory operatorIds = new bytes32[](1);
operatorIds[0] = operatorId;
uint256 index =
registryCoordinator.getQuorumBitmapIndicesAtBlockNumber(blockNumber, operatorIds)[0];
uint256 quorumBitmap =
registryCoordinator.getQuorumBitmapAtBlockNumberByIndex(operatorId, blockNumber, index);
bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap);
return (quorumBitmap, getOperatorState(registryCoordinator, quorumNumbers, blockNumber));
}
/**
* @notice returns the ordered list of operators (id and stake) for each quorum. The AVS coordinator
* may call this function directly to get the operator state for a given block number
* @param registryCoordinator is the registry coordinator to fetch the AVS registry information from
* @param quorumNumbers are the ids of the quorums to get the operator state for
* @param blockNumber is the block number to get the operator state for
* @return 2d array of Operators. For each quorum, an ordered list of Operators
*/
function getOperatorState(
ISlashingRegistryCoordinator registryCoordinator,
bytes memory quorumNumbers,
uint32 blockNumber
) public view returns (Operator[][] memory) {
IStakeRegistry stakeRegistry = registryCoordinator.stakeRegistry();
IIndexRegistry indexRegistry = registryCoordinator.indexRegistry();
IBLSApkRegistry blsApkRegistry = registryCoordinator.blsApkRegistry();
Operator[][] memory operators = new Operator[][](quorumNumbers.length);
for (uint256 i = 0; i < quorumNumbers.length; i++) {
uint8 quorumNumber = uint8(quorumNumbers[i]);
bytes32[] memory operatorIds =
indexRegistry.getOperatorListAtBlockNumber(quorumNumber, blockNumber);
operators[i] = new Operator[](operatorIds.length);
for (uint256 j = 0; j < operatorIds.length; j++) {
operators[i][j] = Operator({
operator: blsApkRegistry.getOperatorFromPubkeyHash(operatorIds[j]),
operatorId: bytes32(operatorIds[j]),
stake: stakeRegistry.getStakeAtBlockNumber(
bytes32(operatorIds[j]), quorumNumber, blockNumber
)
});
}
}
return operators;
}
/**
* @notice this is called by the AVS operator to get the relevant indices for the checkSignatures function
* if they are not running an indexer
* @param registryCoordinator is the registry coordinator to fetch the AVS registry information from
* @param referenceBlockNumber is the block number to get the indices for
* @param quorumNumbers are the ids of the quorums to get the operator state for
* @param nonSignerOperatorIds are the ids of the nonsigning operators
* @return 1) the indices of the quorumBitmaps for each of the operators in the @param nonSignerOperatorIds array at the given blocknumber
* 2) the indices of the total stakes entries for the given quorums at the given blocknumber
* 3) the indices of the stakes of each of the nonsigners in each of the quorums they were a
* part of (for each nonsigner, an array of length the number of quorums they were a part of
* that are also part of the provided quorumNumbers) at the given blocknumber
* 4) the indices of the quorum apks for each of the provided quorums at the given blocknumber
*/
function getCheckSignaturesIndices(
ISlashingRegistryCoordinator registryCoordinator,
uint32 referenceBlockNumber,
bytes calldata quorumNumbers,
bytes32[] calldata nonSignerOperatorIds
) external view returns (CheckSignaturesIndices memory) {
IStakeRegistry stakeRegistry = registryCoordinator.stakeRegistry();
CheckSignaturesIndices memory checkSignaturesIndices;
// get the indices of the quorumBitmap updates for each of the operators in the nonSignerOperatorIds array
checkSignaturesIndices.nonSignerQuorumBitmapIndices = registryCoordinator
.getQuorumBitmapIndicesAtBlockNumber(referenceBlockNumber, nonSignerOperatorIds);
// get the indices of the totalStake updates for each of the quorums in the quorumNumbers array
checkSignaturesIndices.totalStakeIndices =
stakeRegistry.getTotalStakeIndicesAtBlockNumber(referenceBlockNumber, quorumNumbers);
checkSignaturesIndices.nonSignerStakeIndices = new uint32[][](quorumNumbers.length);
for (
uint8 quorumNumberIndex = 0;
quorumNumberIndex < quorumNumbers.length;
quorumNumberIndex++
) {
uint256 numNonSignersForQuorum = 0;
// this array's length will be at most the number of nonSignerOperatorIds, this will be trimmed after it is filled
checkSignaturesIndices.nonSignerStakeIndices[quorumNumberIndex] =
new uint32[](nonSignerOperatorIds.length);
for (uint256 i = 0; i < nonSignerOperatorIds.length; i++) {
// get the quorumBitmap for the operator at the given blocknumber and index
uint192 nonSignerQuorumBitmap = registryCoordinator
.getQuorumBitmapAtBlockNumberByIndex(
nonSignerOperatorIds[i],
referenceBlockNumber,
checkSignaturesIndices.nonSignerQuorumBitmapIndices[i]
);
require(nonSignerQuorumBitmap != 0, OperatorNotRegistered());
// if the operator was a part of the quorum and the quorum is a part of the provided quorumNumbers
if ((nonSignerQuorumBitmap >> uint8(quorumNumbers[quorumNumberIndex])) & 1 == 1) {
// get the index of the stake update for the operator at the given blocknumber and quorum number
checkSignaturesIndices.nonSignerStakeIndices[quorumNumberIndex][numNonSignersForQuorum]
= stakeRegistry.getStakeUpdateIndexAtBlockNumber(
nonSignerOperatorIds[i],
uint8(quorumNumbers[quorumNumberIndex]),
referenceBlockNumber
);
numNonSignersForQuorum++;
}
}
// resize the array to the number of nonSigners for this quorum
uint32[] memory nonSignerStakeIndicesForQuorum = new uint32[](numNonSignersForQuorum);
for (uint256 i = 0; i < numNonSignersForQuorum; i++) {
nonSignerStakeIndicesForQuorum[i] =
checkSignaturesIndices.nonSignerStakeIndices[quorumNumberIndex][i];
}
checkSignaturesIndices.nonSignerStakeIndices[quorumNumberIndex] =
nonSignerStakeIndicesForQuorum;
}
IBLSApkRegistry blsApkRegistry = registryCoordinator.blsApkRegistry();
// get the indices of the quorum apks for each of the provided quorums at the given blocknumber
checkSignaturesIndices.quorumApkIndices =
blsApkRegistry.getApkIndicesAtBlockNumber(quorumNumbers, referenceBlockNumber);
return checkSignaturesIndices;
}
/**
* @notice this function returns the quorumBitmaps for each of the operators in the operatorIds array at the given blocknumber
* @param registryCoordinator is the AVS registry coordinator to fetch the operator information from
* @param operatorIds are the ids of the operators to get the quorumBitmaps for
* @param blockNumber is the block number to get the quorumBitmaps for
*/
function getQuorumBitmapsAtBlockNumber(
ISlashingRegistryCoordinator registryCoordinator,
bytes32[] memory operatorIds,
uint32 blockNumber
) external view returns (uint256[] memory) {
uint32[] memory quorumBitmapIndices =
registryCoordinator.getQuorumBitmapIndicesAtBlockNumber(blockNumber, operatorIds);
uint256[] memory quorumBitmaps = new uint256[](operatorIds.length);
for (uint256 i = 0; i < operatorIds.length; i++) {
quorumBitmaps[i] = registryCoordinator.getQuorumBitmapAtBlockNumberByIndex(
operatorIds[i], blockNumber, quorumBitmapIndices[i]
);
}
return quorumBitmaps;
}
/**
* @notice This function returns the operatorIds for each of the operators in the operators array
* @param registryCoordinator is the AVS registry coordinator to fetch the operator information from
* @param operators is the array of operator address to get corresponding operatorIds for
* @dev if an operator is not registered, the operatorId will be 0
*/
function getBatchOperatorId(
ISlashingRegistryCoordinator registryCoordinator,
address[] memory operators
) external view returns (bytes32[] memory operatorIds) {
operatorIds = new bytes32[](operators.length);
for (uint256 i = 0; i < operators.length; ++i) {
operatorIds[i] = registryCoordinator.getOperatorId(operators[i]);
}
}
/**
* @notice This function returns the operator addresses for each of the operators in the operatorIds array
* @param registryCoordinator is the AVS registry coordinator to fetch the operator information from
* @param operators is the array of operatorIds to get corresponding operator addresses for
* @dev if an operator is not registered, the operator address will be 0
*/
function getBatchOperatorFromId(
ISlashingRegistryCoordinator registryCoordinator,
bytes32[] memory operatorIds
) external view returns (address[] memory operators) {
operators = new address[](operatorIds.length);
for (uint256 i = 0; i < operatorIds.length; ++i) {
operators[i] = registryCoordinator.getOperatorFromId(operatorIds[i]);
}
}
}
"
},
"lib/eigenlayer-middleware/src/interfaces/ISlashingRegistryCoordinator.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
import {IBLSApkRegistry} from "./IBLSApkRegistry.sol";
import {IStakeRegistry} from "./IStakeRegistry.sol";
import {IIndexRegistry} from "./IIndexRegistry.sol";
import {BN254} from "../libraries/BN254.sol";
import {IAllocationManager} from
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IBLSApkRegistry} from "./IBLSApkRegistry.sol";
import {IStakeRegistry, IStakeRegistryTypes} from "./IStakeRegistry.sol";
import {IIndexRegistry} from "./IIndexRegistry.sol";
import {ISocketRegistry} from "./ISocketRegistry.sol";
import {BN254} from "../libraries/BN254.sol";
import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol";
interface ISlashingRegistryCoordinatorErrors {
/// @notice Thrown when array lengths in input parameters don't match.
error InputLengthMismatch();
/// @notice Thrown when an invalid registration type is provided.
error InvalidRegistrationType();
/// @notice Thrown when non-allocation manager calls restricted function.
error OnlyAllocationManager();
/// @notice Thrown when non-ejector calls restricted function.
error OnlyEjector();
/// @notice Thrown when operating on a non-existent quorum.
error QuorumDoesNotExist();
/// @notice Thrown when registering/deregistering with empty bitmap.
error BitmapEmpty();
/// @notice Thrown when registering for already registered quorums.
error AlreadyRegisteredForQuorums();
/// @notice Thrown when registering before ejection cooldown expires.
error CannotReregisterYet();
/// @notice Thrown when unregistered operator attempts restricted operation.
error NotRegistered();
/// @notice Thrown when operator attempts self-churn.
error CannotChurnSelf();
/// @notice Thrown when operator count doesn't match quorum requirements.
error QuorumOperatorCountMismatch();
/// @notice Thrown when operator has insufficient stake for churn.
error InsufficientStakeForChurn();
/// @notice Thrown when attempting to kick operator above stake threshold.
error CannotKickOperatorAboveThreshold();
/// @notice Thrown when updating to zero bitmap.
error BitmapCannotBeZero();
/// @notice Thrown when deregistering from unregistered quorum.
error NotRegisteredForQuorum();
/// @notice Thrown when churn approver salt is already used.
error ChurnApproverSaltUsed();
/// @notice Thrown when operators or quorums list is not sorted ascending.
error NotSorted();
/// @notice Thrown when maximum quorum count is reached.
error MaxQuorumsReached();
/// @notice Thrown when the provided AVS address does not match the expected one.
error InvalidAVS();
/// @notice Thrown when attempting to kick an operator that is not registered.
error OperatorNotRegistered();
/// @notice Thrown when lookAheadPeriod is greater than or equal to DEALLOCATION_DELAY.
error LookAheadPeriodTooLong();
/// @notice Thrown when the number of operators in a quorum would exceed the maximum allowed.
error MaxOperatorCountReached();
}
interface ISlashingRegistryCoordinatorTypes {
/// @notice Core data structure for tracking operator information.
/// @dev Links an operator's unique identifier with their current registration status.
/// @param operatorId Unique identifier for the operator, typically derived from their BLS public key.
/// @param status Current registration state of the operator in the system.
struct OperatorInfo {
bytes32 operatorId;
OperatorStatus status;
}
/// @notice Records historical changes to an operator's quorum registrations.
/// @dev Used for querying an operator's quorum memberships at specific block numbers.
/// @param updateBlockNumber Block number when this update occurred (inclusive).
/// @param nextUpdateBlockNumber Block number when the next update occurred (exclusive), or 0 if this is the latest update.
/// @param quorumBitmap Bitmap where each bit represents registration in a specific quorum (1 = registered, 0 = not registered).
struct QuorumBitmapUpdate {
uint32 updateBlockNumber;
uint32 nextUpdateBlockNumber;
uint192 quorumBitmap;
}
/// @notice Configuration parameters for operator management within a quorum.
/// @dev All BIPs (Basis Points) values are in relation to BIPS_DENOMINATOR (10000).
/// @param maxOperatorCount Maximum number of operators allowed in the quorum.
/// @param kickBIPsOfOperatorStake Required stake ratio (in BIPs) between new and existing operator for churn.
/// Example: 10500 means new operator needs 105% of existing operator's stake.
/// @param kickBIPsOfTotalStake Minimum stake ratio (in BIPs) of total quorum stake an operator must maintain.
/// Example: 100 means operator needs 1% of total quorum stake to avoid being churned.
struct OperatorSetParam {
uint32 maxOperatorCount;
uint16 kickBIPsOfOperatorStake;
uint16 kickBIPsOfTotalStake;
}
/// @notice Parameters for removing an operator during churn.
/// @dev Used in registerOperatorWithChurn to specify which operator to replace.
/// @param quorumNumber The quorum from which to remove the operator.
/// @param operator Address of the operator to be removed.
struct OperatorKickParam {
uint8 quorumNumber;
address operator;
}
/// @notice Represents the registration state of an operator.
/// @dev Used to track an operator's lifecycle in the system.
/// @custom:enum NEVER_REGISTERED The operator has never registered with the system.
/// @custom:enum REGISTERED The operator is currently registered and active.
/// @custom:enum DEREGISTERED The operator was previously registered but has since deregistered.
enum OperatorStatus {
NEVER_REGISTERED,
REGISTERED,
DEREGISTERED
}
/**
* @notice Enum representing the type of operator registration.
* @custom:enum NORMAL Represents a normal operator registration.
* @custom:enum CHURN Represents an operator registration during a churn event.
*/
enum RegistrationType {
NORMAL,
CHURN
}
/**
* @notice Data structure for storing the results of a registerOperator call.
* @dev Contains arrays storing per-quorum information about operator counts and stakes.
* @param numOperatorsPerQuorum For each quorum the operator registered for, stores the number of operators registered.
* @param operatorStakes For each quorum the operator registered for, stores the stake of the operator in the quorum.
* @param totalStakes For each quorum the operator registered for, stores the total stake of the quorum.
*/
struct RegisterResults {
uint32[] numOperatorsPerQuorum;
uint96[] operatorStakes;
uint96[] totalStakes;
}
}
interface ISlashingRegistryCoordinatorEvents is ISlashingRegistryCoordinatorTypes {
/**
* @notice Emitted when an operator registers for service in one or more quorums.
* @dev Emitted in _registerOperator() and _registerOperatorToOperatorSet().
* @param operator The address of the registered operator.
* @param operatorId The unique identifier of the operator (BLS public key hash).
*/
event OperatorRegistered(address indexed operator, bytes32 indexed operatorId);
/**
* @notice Emitted when an operator deregisters from service in one or more quorums.
* @dev Emitted in _deregisterOperator().
* @param operator The address of the deregistered operator.
* @param operatorId The unique identifier of the operator (BLS public key hash).
*/
event OperatorDeregistered(address indexed operator, bytes32 indexed operatorId);
/**
* @notice Emitted when a new quorum is created.
* @param quorumNumber The identifier of the quorum being created.
* @param operatorSetParams The operator set parameters for the quorum.
* @param minimumStake The minimum stake required for operators in this quorum.
* @param strategyParams The strategy parameters for stake calculation.
* @param stakeType The type of stake being tracked (TOTAL_DELEGATED or TOTAL_SLASHABLE).
* @param lookAheadPeriod The number of blocks to look ahead when calculating slashable stake (only used for TOTAL_SLASHABLE).
*/
event QuorumCreated(
uint8 indexed quorumNumber,
OperatorSetParam operatorSetParams,
uint96 minimumStake,
IStakeRegistryTypes.StrategyParams[] strategyParams,
IStakeRegistryTypes.StakeType stakeType,
uint32 lookAheadPeriod
);
/**
* @notice Emitted when a quorum's operator set parameters are updated.
* @dev Emitted in _setOperatorSetParams().
* @param quorumNumber The identifier of the quorum being updated.
* @param operatorSetParams The new operator set parameters for the quorum.
*/
event OperatorSetParamsUpdated(uint8 indexed quorumNumber, OperatorSetParam operatorSetParams);
/**
* @notice Emitted when the churn approver address is updated.
* @dev Emitted in _setChurnApprover().
* @param prevChurnApprover The previous churn approver address.
* @param newChurnApprover The new churn approver address.
*/
event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover);
/**
* @notice Emitted when the AVS address is updated.
* @param prevAVS The previous AVS address.
* @param newAVS The new AVS address.
*/
event AVSUpdated(address prevAVS, address newAVS);
/**
* @notice Emitted when the ejector address is updated.
* @dev Emitted in _setEjector().
* @param prevEjector The previous ejector address.
* @param newEjector The new ejector address.
*/
event EjectorUpdated(address prevEjector, address newEjector);
/**
* @notice Emitted when all operators in a quorum are updated simultaneously.
* @dev Emitted in updateOperatorsForQuorum().
* @param quorumNumber The identifier of the quorum being updated.
* @param blocknumber The block number at which the quorum update occurred.
*/
event QuorumBlockNumberUpdated(uint8 indexed quorumNumber, uint256 blocknumber);
/**
* @notice Emitted when an operator's socket is updated.
* @dev Emitted in updateSocket().
* @param operatorId The unique identifier of the operator (BLS public key hash).
* @param socket The new socket address for the operator (typically an IP address).
*/
event OperatorSocketUpdate(bytes32 indexed operatorId, string socket);
/**
* @notice Emitted when the ejection cooldown period is updated.
* @dev Emitted in setEjectionCooldown().
* @param prevEjectionCooldown The previous cooldown duration in seconds.
* @param newEjectionCooldown The new cooldown duration in seconds.
*/
event EjectionCooldownUpdated(uint256 prevEjectionCooldown, uint256 newEjectionCooldown);
}
interface ISlashingRegistryCoordinator is
IAVSRegistrar,
ISlashingRegistryCoordinatorErrors,
ISlashingRegistryCoordinatorEvents
{
/// IMMUTABLES & CONSTANTS
/**
* @notice EIP-712 typehash for operator churn approval signatures.
* @return The typehash constant.
*/
function OPERATOR_CHURN_APPROVAL_TYPEHASH() external view returns (bytes32);
/**
* @notice EIP-712 typehash for pubkey registration signatures.
* @return The typehash constant.
*/
function PUBKEY_REGISTRATION_TYPEHASH() external view returns (bytes32);
/**
* @notice Reference to the BLSApkRegistry contract.
* @return The BLSApkRegistry contract interface.
*/
function blsApkRegistry() external view returns (IBLSApkRegistry);
/**
* @notice Reference to the StakeRegistry contract.
* @return The StakeRegistry contract interface.
*/
function stakeRegistry() external view returns (IStakeRegistry);
/**
* @notice Reference to the IndexRegistry contract.
* @return The IndexRegistry contract interface.
*/
function indexRegistry() external view returns (IIndexRegistry);
/**
* @notice Reference to the AllocationManager contract.
* @return The AllocationManager contract interface.
* @dev This is only relevant for Slashing AVSs
*/
function allocationManager() external view returns (IAllocationManager);
/**
* @notice Reference to the SocketRegistry contract.
* @return The SocketRegistry contract interface.
*/
function socketRegistry() external view returns (ISocketRegistry);
/// STORAGE
/**
* @notice The total number of quorums that have been created.
* @return The count of quorums.
*/
function quorumCount() external view returns (uint8);
/**
* @notice Checks if a churn approver salt has been used.
* @param salt The salt to check.
* @return True if the salt has been used, false otherwise.
*/
function isChurnApproverSaltUsed(
bytes32 salt
) external view returns (bool);
/**
* @notice Gets the last block number when all operators in a quorum were updated.
* @param quorumNumber The quorum identifier.
* @return The block number of the last update.
*/
function quorumUpdateBlockNumber(
uint8 quorumNumber
) external view returns (uint256);
/**
* @notice The address authorized to approve operator churn operations.
* @return The churn approver address.
*/
function churnApprover() external view returns (address);
/**
* @notice The address authorized to forcibly eject operators.
* @return The ejector address.
*/
function ejector() external view returns (address);
/**
* @notice Gets the timestamp of an operator's last ejection.
* @param operator The operator address.
* @return The timestamp of the last ejection.
*/
function lastEjectionTimestamp(
address operator
) external view returns (uint256);
/**
* @notice The cooldown period after ejection before an operator can re-register.
* @return The cooldown duration in seconds.
*/
function ejectionCooldown() external view returns (uint256);
/// ACTIONS
/**
* @notice Updates stake weights for specified operators. If any operator is found to be below
* the minimum stake for their registered quorums, they are deregistered from those quorums.
* @param operators The operators whose stakes should be updated.
* @dev Stakes are queried from the Eigenlayer core DelegationManager contract.
* @dev WILL BE DEPRECATED IN FAVOR OF updateOperatorsForQuorum
*/
function updateOperators(
address[] memory operators
) external;
/**
* @notice For each quorum in `quorumNumbers`, updates the StakeRegistry's view of ALL its registered operators' stakes.
* Each quorum's `quorumUpdateBlockNumber` is also updated, which tracks the most recent block number when ALL registered
* operators were updated.
* @dev stakes are queried from the Eigenlayer core DelegationManager contract
* @param operatorsPerQuorum for each quorum in `quorumNumbers`, this has a corresponding list of operators to update.
* @dev Each list of operator addresses MUST be sorted in ascending order
* @dev Each list of operator addresses MUST represent the entire list of registered operators for the corresponding quorum
* @param quorumNumbers is an ordered byte array containing the quorum numbers being updated
* @dev invariant: Each list of `operatorsPerQuorum` MUST be a sorted version of `IndexRegistry.getOperatorListAtBlockNumber`
* for the corresponding quorum.
* @dev note on race condition: if an operator registers/deregisters for any quorum in `quorumNumbers` after a txn to
* this method is broadcast (but before it is executed), the method will fail
*/
function updateOperatorsForQuorum(
address[][] memory operatorsPerQuorum,
bytes calldata quorumNumbers
) external;
/**
* @notice Updates the socket of the msg.sender given they are a registered operator.
* @param socket The new socket address for the operator (typically an IP address).
* @dev Will revert if msg.sender is not a registered operator.
*/
function updateSocket(
string memory socket
) external;
/**
* @notice Forcibly removes an operator from specified quorums and sets their ejection timestamp.
* @param operator The operator address to eject.
* @param quorumNumbers The quorum numbers to eject the operator from.
* @dev Can only be called by the ejector address.
* @dev The operator cannot re-register until ejectionCooldown period has passed.
*/
function ejectOperator(address operator, bytes memory quorumNumbers) external;
/**
* @notice Creates a new quorum that tracks total delegated stake for operators.
* @param operatorSetParams Configures the quorum's max operator count and churn parameters.
* @param minimumStake Sets the minimum stake required for an operator to register or remain registered.
* @param strategyParams A list of strategies and multipliers used by the StakeRegistry to calculate
* an operator's stake weight for the quorum.
* @dev For m2 AVS this function has the same behavior as createQuorum before.
* @dev For migrated AVS that enable operator sets this will create a quorum that measures total delegated stake for operator set.
*/
function createTotalDelegatedStakeQuorum(
OperatorSetParam memory operatorSetParams,
uint96 minimumStake,
IStakeRegistryTypes.StrategyParams[] memory strategyParams
) external;
/**
* @notice Creates a new quorum that tracks slashable stake for operators.
* @param operatorSetParams Configures the quorum's max operator count and churn parameters.
* @param minimumStake Sets the minimum stake required for an operator to register or remain registered.
* @param strategyParams A list of strategies and multipliers used by the StakeRegistry to calculate
* an operator's stake weight for the quorum.
* @param lookAheadPeriod The number of blocks to look ahead when calculating slashable stake.
* @dev Can only be called when operator sets are enabled.
*/
function createSlashableStakeQuorum(
OperatorSetParam memory operatorSetParams,
uint96 minimumStake,
IStakeRegistryTypes.StrategyParams[] memory strategyParams,
uint32 lookAheadPeriod
) external;
/**
* @notice Updates the configuration parameters for an existing operator set quorum.
* @param quorumNumber The identifier of the quorum to update.
* @param operatorSetParams The new operator set parameters to apply.
* @dev Can only be called by the contract owner.
*/
function setOperatorSetParams(
uint8 quorumNumber,
OperatorSetParam memory operatorSetParams
) external;
/**
* @notice Updates the address authorized to approve operator churn operations.
* @param _churnApprover The new churn approver address.
* @dev Can only be called by the contract owner.
* @dev The churn approver is responsible for signing off on operator replacements in full quorums.
*/
function setChurnApprover(
address _churnApprover
) external;
/**
* @notice Updates the address authorized to forcibly eject operators.
* @param _ejector The new ejector address.
* @dev Can only be called by the contract owner.
* @dev The ejector can force-remove operators from quorums regardless of their stake.
*/
function setEjector(
address _ejector
) external;
/**
* @notice Updates the duration operators must wait after ejection before re-registering.
* @param _ejectionCooldown The new cooldown duration in seconds.
* @dev Can only be called by the contract owner.
*/
function setEjectionCooldown(
uint256 _ejectionCooldown
) external;
/**
* @notice Updates the avs address for this AVS (used for UAM integration in EigenLayer)
* @param _avs The new avs address
* @dev Can only be called by the contract owner
* @dev NOTE: Updating this value will break existing OperatorSets and UAM integration. This value should only be set once.
*/
function setAVS(
address _avs
) external;
/// VIEW
/**
* @notice Returns the hash of the message that operators must sign with their BLS key to register
* @param operator The operator's Ethereum address
*/
function calculatePubkeyRegistrationMessageHash(
address operator
) external view returns (bytes32);
/**
* @notice Returns the operator set parameters for a given quorum.
* @param quorumNumber The identifier of the quorum to query.
* @return The OperatorSetParam struct containing max operator count and churn thresholds.
*/
function getOperatorSetParams(
uint8 quorumNumber
) external view returns (OperatorSetParam memory);
/**
* @notice Returns the complete operator information for a given address.
* @param operator The operator address to query.
* @return An OperatorInfo struct containing the operator's ID and registration status.
*/
function getOperator(
address operator
) external view returns (OperatorInfo memory);
/**
* @notice Returns the unique identifier for a given operator address.
* @param operator The operator address to query.
* @return The operator's ID (derived from their BLS public key hash).
*/
function getOperatorId(
address operator
) external view returns (bytes32);
/**
* @notice Returns the operator address associated with a given operator ID.
* @param operatorId The unique identifier to look up.
* @return The operator's address.
* @dev Returns address(0) if the ID is not registered.
*/
function getOperatorFromId(
bytes32 operatorId
) external view returns (address);
/**
* @notice Returns the current registration status for a given operator.
* @param operator The operator address to query.
* @return The operator's status (NEVER_REGISTERED, REGISTERED, or DEREGISTERED).
*/
function getOperatorStatus(
address operator
) external view returns (OperatorStatus);
/**
* @notice Returns the indices needed to look up quorum bitmaps for operators at a specific block.
* @param blockNumber The historical block number to query.
* @param operatorIds Array of operator IDs to get indices for.
* @return Array of indices corresponding to each operator ID.
* @dev Reverts if any operator had not yet registered at the specified block.
* @dev This function is designed to find proper inputs for getQuorumBitmapAtBlockNumberByIndex.
*/
function getQuorumBitmapIndicesAtBlockNumber(
uint32 blockNumber,
bytes32[] memory operatorIds
) external view returns (uint32[] memory);
/**
* @notice Returns the quorum bitmap for an operator at a specific historical block.
* @param operatorId The operator's unique identifier.
* @param blockNumber The historical block number to query.
* @param index The index in the operator's bitmap history (from getQuorumBitmapIndicesAtBlockNumber).
* @return The quorum bitmap showing which quorums the operator was registered for.
* @dev Reverts if the index is incorrect for the specified block number.
*/
function getQuorumBitmapAtBlockNumberByIndex(
bytes32 operatorId,
uint32 blockNumber,
uint256 index
) external view returns (uint192);
/**
* @notice Returns a specific update from an operator's quorum bitmap history.
* @param operatorId The operator's unique identifier.
* @param index The index in the bitmap history to query.
* @return The QuorumBitmapUpdate struct at that index.
*/
function getQuorumBitmapUpdateByIndex(
bytes32 operatorId,
uint256 index
) external view returns (QuorumBitmapUpdate memory);
/**
* @notice Returns the current quorum bitmap for an operator.
* @param operatorId The operator's unique identifier.
* @return A bitmap where each bit represents registration in a specific quorum.
* @dev Returns 0 if the operator is not registered for any quorums.
*/
function getCurrentQuorumBitmap(
bytes32 operatorId
) external view returns (uint192);
/**
* @notice Returns the number of updates in an operator's bitmap history.
* @param operatorId The operator's unique identifier.
* @return The length of the bitmap history array.
*/
function getQuorumBitmapHistoryLength(
bytes32 operatorId
) external view returns (uint256);
/**
* @notice Calculates the digest hash that must be signed by the churn approver.
* @param registeringOperator The address of the operator attempting to register.
* @param registeringOperatorId The unique ID of the registering operator.
* @param operatorKickParams Parameters specifying which operators to replace in full quorums.
* @param salt Random value to ensure signature uniqueness.
* @param expiry Timestamp after which the signature becomes invalid.
* @return The EIP-712 typed data hash to be signed.
*/
function calculateOperatorChurnApprovalDigestHash(
address registeringOperator,
bytes32 registeringOperatorId,
OperatorKickParam[] memory operatorKickParams,
bytes32 salt,
uint256 expiry
) external view returns (bytes32);
/**
* @notice Returns the message hash that an operator must sign to register their BLS public key.
* @param operator The address of the operator registering their key.
* @return A point on the G1 curve representing the message hash.
*/
function pubkeyRegistrationMessageHash(
address operator
) external view returns (BN254.G1Point memory);
/**
* @notice Returns the avs address for this AVS (used for UAM integration in EigenLayer)
* @dev NOTE: Updating this value will break existing OperatorSets and UAM integration. This value should only be set once.
* @return The avs address
*/
function avs() external view returns (address);
}
"
},
"lib/eigenlayer-middleware/src/interfaces/IBLSApkRegistry.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
import {BN254} from "../libraries/BN254.sol";
interface IBLSApkRegistryErrors {
/// @notice Thrown when a non-RegistryCoordinator address calls a restricted function.
error OnlyRegistryCoordinatorOwner();
/// @notice Thrown when attempting to initialize a quorum that already exists.
error QuorumAlreadyExists();
/// @notice Thrown when a quorum does not exist.
error QuorumDoesNotExist();
/// @notice Thrown when a BLS pubkey provided is zero pubkey
error ZeroPubKey();
/// @notice Thrown when an operator has already registered a BLS pubkey.
error OperatorAlreadyRegistered();
/// @notice Thrown when the operator is not registered.
error OperatorNotRegistered();
/// @notice Thrown when a BLS pubkey has already been registered for an operator.
error BLSPubkeyAlreadyRegistered();
/// @notice Thrown when either the G1 signature is wrong, or G1 and G2 private key do not match.
error InvalidBLSSignatureOrPrivateKey();
/// @notice Thrown when the quorum apk update block number is too recent.
error BlockNumberTooRecent();
/// @notice Thrown when blocknumber and index provided is not the latest apk update.
error BlockNumberNotLatest();
/// @notice Thrown when the block number is before the first update.
error BlockNumberBeforeFirstUpdate();
/// @notice Thrown when a G2 pubkey has already been set for an operator
error G2PubkeyAlreadySet();
}
interface IBLSApkRegistryTypes {
/// @notice Tracks the history of aggregate public key updates for a quorum.
/// @dev Each update contains a hash of the aggregate public key and block numbers for timing.
/// @param apkHash First 24 bytes of keccak256(apk_x0, apk_x1, apk_y0, apk_y1) representing the aggregate public key.
/// @param updateBlockNumber Block number when this update occurred (inclusive).
/// @param nextUpdateBlockNumber Block number when the next update occurred (exclusive), or 0 if this is the latest update.
struct ApkUpdate {
bytes24 apkHash;
uint32 updateBlockNumber;
uint32 nextUpdateBlockNumber;
}
/// @notice Parameters required when registering a new BLS public key.
/// @dev Contains the registration signature and both G1/G2 public key components.
/// @param pubkeyRegistrationSignature Registration message signed by operator's private key to prove ownership.
/// @param pubkeyG1 The operator's public key in G1 group format.
/// @param pubkeyG2 The operator's public key in G2 group format, must correspond to the same private key as pubkeyG1.
struct PubkeyRegistrationParams {
BN254.G1Point pubkeyRegistrationSignature;
BN254.G1Point pubkeyG1;
BN254.G2Point pubkeyG2;
}
}
interface IBLSApkRegistryEvents is IBLSApkRegistryTypes {
/*
* @notice Emitted when `operator` registers their BLS public key pair (`pubkeyG1` and `pubkeyG2`).
* @param operator The address of the operator registering the keys.
* @param pubkeyG1 The operator's G1 public key.
* @param pubkeyG2 The operator's G2 public key.
*/
event NewPubkeyRegistration(
address indexed operator, BN254.G1Point pubkeyG1, BN254.G2Point pubkeyG2
);
/*
* @notice Emitted when `operator`'s pubkey is registered for `quorumNumbers`.
* @param operator The address of the operator being registered.
* @param operatorId The unique identifier for this operator (pubkey hash).
* @param quorumNumbers The quorum numbers the operator is being registered for.
*/
event OperatorAddedToQuorums(address operator, bytes32 operatorId, bytes quorumNumbers);
/*
* @notice Emitted when `operator`'s pubkey is deregistered from `quorumNumbers`.
* @param operator The address of the operator being deregistered.
* @param operatorId The unique identifier for this operator (pubkey hash).
* @param quorumNumbers The quorum numbers the operator is being deregistered from.
*/
event OperatorRemovedFromQuorums(address operator, bytes32 operatorId, bytes quorumNumbers);
/// @notice Emitted when a G2 public key is registered for an operator
event NewG2PubkeyRegistration(address indexed operator, BN254.G2Point pubkeyG2);
}
interface IBLSApkRegistry is IBLSApkRegistryErrors, IBLSApkRegistryEvents {
/* STORAGE */
/*
* @notice Returns the address of the registry coordinator contract.
* @return The address of the registry coordinator.
* @dev This value is immutable and set during contract construction.
*/
function registryCoordinator() external view returns (address);
/*
* @notice Maps `operator` to their BLS public key hash (`operatorId`).
* @param operator The address of the operator.
* @return operatorId The hash of the operator's BLS public key.
*/
function operatorToPubkeyHash(
address operator
) external view returns (bytes32 operatorId);
/*
* @notice Maps `pubkeyHash` to their corresponding `operator` address.
* @param pubkeyHash The hash of a BLS public key.
* @return operator The address of the operator who registered this public key.
*/
function pubkeyHashToOperator(
bytes32 pubkeyHash
) external view returns (address operator);
/*
* @notice Maps `operator` to their BLS public key in G1.
* @dev Returns a non-encoded BN254.G1Point.
* @param operator The address of the operator.
* @return The operator's BLS public key in G1.
*/
function operatorToPubkey(
address operator
) external view returns (uint256, uint256);
/*
* @notice Maps `operator` to their BLS public key in G2.
* @param operator The address of the operator.
* @return The operator's BLS public key in G2.
*/
function getOperatorPubkeyG2(
address operator
) external view returns (BN254.G2Point memory);
/*
* @notice Stores the history of aggregate public key updates for `quorumNumber` at `index`.
* @dev Returns a non-encoded IBLSApkRegistryTypes.ApkUpdate.
* @param quorumNumber The identifier of the quorum.
* @param index The index in the history array.
* @return The APK update entry at the specified index for the given quorum.
* @dev Each entry contains the APK hash, update block number, and next update block number.
*/
function apkHistory(
uint8 quorumNumber,
uint256 index
) external view returns (bytes24, uint32, uint32);
/*
* @notice Maps `quorumNumber` to their current aggregate public key.
* @dev Returns a non-encoded BN254.G1Point.
* @param quorumNumber The identifier of the quorum.
* @return The current APK as a G1 point.
*/
function currentApk(
uint8 quorumNumber
) external view returns (uint256, uint256);
/* ACTIONS */
/*
* @notice Registers `operator`'s pubkey for `quorumNumbers`.
* @param operator The address of the operator to register.
* @param quorumNumbers The quorum numbers to register for, where each byte is an 8-bit integer.
* @dev Access restricted to the RegistryCoordinator.
* @dev Preconditions (assumed, not validated):
* 1. `quorumNumbers` has no duplicates
* 2. `quorumNumbers.length` != 0
* 3. `quorumNumbers` is ordered ascending
* 4. The operator is not already registered
*/
function registerOperator(address operator, bytes calldata quorumNumbers) external;
/*
* @notice Deregisters `operator`'s pubkey from `quorumNumbers`.
* @param operator The address of the operator to deregister.
* @param quorumNumbers The quorum numbers to deregister from, where each byte is an 8-bit integer.
* @dev Access restricted to the RegistryCoordinator.
* @dev Preconditions (assumed, not validated):
* 1. `quorumNumbers` has no duplicates
* 2. `quorumNumbers.length` != 0
* 3. `quorumNumbers` is ordered ascending
* 4. The operator is not already deregistered
* 5. `quorumNumbers` is a subset of the operator's registered quorums
*/
function deregisterOperator(address operator, bytes calldata quorumNumbers) external;
/*
* @notice Initializes `quorumNumber` by pushing its first APK update.
* @param quorumNumber The number of the new quorum.
*/
function initializeQuorum(
uint8 quorumNumber
) external;
/*
* @notice Registers `operator` as the owner of a BLS public key using `params` and `pubkeyRegistrationMessageHash`.
* @param operator The operator for whom the key is being registered.
* @param params Contains the G1 & G2 public keys and ownership proof signature.
* @param pubkeyRegistrationMessageHash The hash that must be signed to prove key ownership.
* @return operatorId The unique identifier (pubkey hash) for this operator.
* @dev Called by the RegistryCoordinator.
*/
function registerBLSPublicKey(
address operator,
IBLSApkRegistryTypes.PubkeyRegistrationParams calldata params,
BN254.G1Point calldata pubkeyRegistrationMessageHash
) external returns (bytes32 operatorId);
/* VIEW */
/*
* @notice Returns the pubkey and pubkey hash of `operator`.
* @param operator The address of the operator.
* @return The operator's G1 public key and its hash.
* @dev Reverts if the operator has not registered a valid pubkey.
*/
function getRegisteredPubkey(
address operator
) external view returns (BN254.G1Point memory, bytes32);
/*
* @notice Returns the APK indices at `blockNumber` for `quorumNumbers`.
* @param quorumNumbers The quorum numbers to get indices for.
* @param blockNumber The block number to query at.
* @return Array of indices corresponding to each quorum number.
*/
function getApkIndicesAtBlockNumber(
bytes calldata quorumNumbers,
uint256 blockNumber
) external view returns (uint32[] memory);
/*
* @notice Returns the current aggregate public key for `quorumNumber`.
* @param quorumNumber The quorum to query.
* @return The current APK as a G1 point.
*/
function getApk(
uint8 quorumNumber
) external view returns (BN254.G1Point memory);
/*
* @notice Returns an APK update entry for `quorumNumber` at `index`.
* @param quorumNumber The quorum to query.
* @param index The index in the APK history.
* @return The APK update entry.
*/
function getApkUpdateAtIndex(
uint8 quorumNumber,
uint256 index
) external view returns (IBLSApkRegistryTypes.ApkUpdate memory);
/*
* @notice Gets the 24-byte hash of `quorumNumber`'s APK at `blockNumber` and `index`.
* @param quorumNumber The quorum to query.
* @param blockNumber The block number to get the APK hash for.
* @param index The index in the APK history.
* @return The 24-byte APK hash.
* @dev Called by checkSignatures in BLSSignatureChecker.sol.
*/
function getApkHashAtBlockNumberAndIndex(
uint8 quorumNumber,
uint32 blockNumber,
uint256 index
) external view returns (bytes24);
/*
* @notice Returns the number of APK updates for `quorumNumber`.
* @param quorumNumber The quorum to query.
* @return The length of the APK history.
*/
function getApkHistoryLength(
uint8 quorumNumber
) external view returns (uint32);
/*
* @notice Maps `operator` to their corresponding public key hash.
* @param operator The address of the operator.
* @return operatorId The hash of the operator's BLS public key.
* @dev Returns bytes32(0) if the operator hasn't registered a key.
*/
function getOperatorId(
address operator
) external view returns (bytes32 operatorId);
/*
* @notice Maps `pubkeyHash` to their corresponding operator address.
* @param pubkeyHash The hash of a BLS public key.
* @return operator The address of the operator who registered this public key.
* @dev Returns address(0) if the public key hash hasn't been registered.
*/
function getOperatorFromPubkeyHash(
bytes32 pubkeyHash
) external view returns (address operator);
/**
* @notice Gets an operator's ID if it exists, or registers a new BLS public key and returns the new ID
* @param operator The address of the operator
* @param params The parameters for registering a new BLS public key
* @param pubkeyRegistrationMessageHash The hash of the message to sign for registration
* @return operatorId The operator's ID (pubkey hash)
*/
function getOrRegisterOperatorId(
address operator,
PubkeyRegistrationParams calldata params,
BN254.G1Point calldata pubkeyRegistrationMessageHash
) external returns (bytes32 operatorId);
}
"
},
"lib/eigenlayer-middleware/src/interfaces/IStakeRegistry.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
import {IDelegationManager} from
"eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
/// @notice Interface containing all error definitions for the StakeRegistry contract.
interface IStakeRegistryErrors {
/// @dev Thrown when the caller is not the registry coordinator
error OnlySlashingRegistryCoordinator();
/// @dev Thrown when the caller is not the owner of the registry coordinator
error OnlySlashingRegistryCoordinatorOwner();
/// @dev Thrown when the stake is below the minimum required for a quorum
error BelowMinimumStakeRequirement();
/// @notice Thrown when attempting to create a quorum that already exists.
error QuorumAlreadyExists();
/// @notice Thrown when attempting to interact with a quorum that does not exist.
error QuorumDoesNotExist();
/// @notice Thrown when two array parameters have mismatching lengths.
error InputArrayLengthMismatch();
/// @notice Thrown when an input array has zero length.
error InputArrayLengthZero();
/// @notice Thrown when a duplicate strategy is provided in an input array.
error InputDuplicateStrategy();
/// @notice Thrown when a multiplier input is zero.
error InputMultiplierZero();
/// @notice Thrown when the provided block number is invalid for the stake update.
error InvalidBlockNumber();
/// @notice Thrown when attempting to access stake history that doesn't exist for a quorum.
error EmptyStakeHistory();
/// @notice Thrown when the quorum is not slashable and the caller attempts to set the look ahead period.
error QuorumNotSlashable();
}
interface IStakeRegistryTypes {
/// @notice Defines the type of stake being tracked.
/// @param TOTAL_DELEGATED Represents the total delegated stake.
/// @param TOTAL_SLASHABLE Represents the total slashable stake.
enum StakeType {
TOTAL_DELEGATED,
TOTAL_SLASHABLE
}
/// @notice Stores stake information for an operator or total stakes at a specific block.
/// @param updateBlockNumber The block number at which the stake amounts were updated.
/// @param nextUpdateBlockNumber The block number at which the next update occurred (0 if no next update).
/// @param stake The stake weight for the quorum.
struct StakeUpdate {
uint32 updateBlockNumber;
uint32 nextUpdateBlockNumber;
uint96 stake;
}
/// @notice Parameters for weighing a particular strategy's stake.
/// @param strategy The strategy contract address.
/// @param multiplier The weight multiplier applied to the strategy's stake.
struct StrategyParams {
IStrategy strategy;
uint96 multiplier;
}
}
interface IStakeRegistryEvents is IStakeRegistryTypes {
/**
* @notice Emitted when an operator's stake is updated.
* @param operatorId The unique identifier of the operator (indexed).
* @param quorumNumber The quorum number for which the stake was updated.
* @param stake The new stake amount.
*/
event OperatorStakeUpdate(bytes32 indexed operatorId, uint8 quorumNumber, uint96 stake);
/**
* @notice Emitted when the look ahead period for checking operator shares is updated.
* @param oldLookAheadBlocks The previous look ahead period.
* @param newLookAheadBlocks The new look ahead period.
*/
event LookAheadPeriodChanged(uint32 oldLookAheadBlocks, uint32 newLookAheadBlocks);
/**
* @notice Emitted when the stake type is updated.
* @param newStakeType The new stake type being set.
*/
event StakeTypeSet(StakeType newStakeType);
/**
* @notice Emitted when the minimum stake for a quorum is updated.
* @param quorumNumber The quorum number being updated (indexed).
* @param minimumStake The new minimum stake requirement.
*/
event MinimumStakeForQuorumUpdated(uint8 indexed quorumNumber, uint96 minimumStake);
/**
* @notice Emitted when a new quorum is created.
* @param quorumNumber The number of the newly created quorum (indexed).
*/
event QuorumCreated(uint8 indexed quorumNumber);
/**
* @notice Emitted when a strategy is added to a quorum.
* @param quorumNumber The quorum number the strategy was added to (indexed).
* @param strategy The strategy contract that was added.
*/
event StrategyAddedToQuorum(uint8 indexed quorumNumber, IStrategy strategy);
/**
* @notice Emitted when a strategy is removed from a quorum.
* @param quorumNumber The quorum number the strategy was removed from (indexed).
* @param strategy The strategy contract that was removed.
*/
event StrategyRemovedFromQuorum(uint8 indexed quorumNumber, IStrategy strategy);
/**
* @notice Emitted when a strategy's multiplier is updated.
* @param quorumNumber The quorum number for the strategy update (indexed).
* @param strategy The strategy contract being updated.
* @param multiplier The new multiplier value.
*/
event StrategyMultiplierUpdated(
uint8 indexed quorumNumber, IStrategy strategy, uint256 multiplier
);
}
interface IStakeRegistry is IStakeRegistryErrors, IStakeRegistryEvents {
/// STATE
/**
* @notice Returns the EigenLayer delegation manager contract.
*/
function delegation() external view returns (IDelegationManager);
/// ACTIONS
/**
* @notice Registers the `operator` with `operatorId` for the specified `quorumNumbers`.
* @param operator The address of the operator to register.
* @param operatorId The id of the operator to register.
* @param quorumNumbers The quorum numbers the operator is registering for, where each byte is an 8 bit integer quorumNumber.
* @return operatorStakes The operator's current stake for each quorum.
* @return totalStakes The total stake for each quorum.
* @dev Access restricted to the RegistryCoordinator.
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates.
* 2) `quorumNumbers.length` != 0.
* 3) `quorumNumbers` is ordered in ascending order.
* 4) The operator is not already registered.
*/
function registerOperator(
address operator,
bytes32 operatorId,
bytes memory quorumNumbers
) external returns (uint96[] memory operatorStakes, uint96[] memory totalStakes);
/**
* @notice Deregisters the operator with `operatorId` for the specified `quorumNumbers`.
* @param operatorId The id of the operator to deregister.
* @param quorumNumbers The quorum numbers the operator is deregistering from, where each byte is an 8 bit integer quorumNumber.
* @dev Access restricted to the RegistryCoordinator.
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates.
* 2) `quorumNumbers.length` != 0.
* 3) `quorumNumbers` is ordered in ascending order.
* 4) The operator is not already deregistered.
* 5) `quorumNumbers` is a subset of the quorumNumbers that the operator is registered for.
*/
function deregisterOperator(bytes32 operatorId, bytes memory quorumNumbers) external;
/**
* @notice Called by the registry coordinator to update the stake of a list of operators for a specific quorum.
* @param operators The addresses of the operators to update.
* @param operatorIds The ids of the operators to update.
* @param quorumNumber The quorum number to update the stake for.
* @return A list of bools, true if the corresponding operator should be deregistered since they no longer meet the minimum stake requirement.
*/
function updateOperatorsStake(
address[] memory operators,
bytes32[] memory operatorIds,
uint8 quorumNumber
) external returns (bool[] memory);
/**
* @notice Initialize a new quorum created by the registry coordinator by setting strategies, weights, and minimum stake.
* @param quorumNumber The number of the quorum to initialize.
* @param minimumStake The minimum stake required for the quorum.
* @param strategyParams The initial strategy parameters for the quorum.
*/
function initializeDelegatedStakeQuorum(
uint8 quorumNumber,
uint96 minimumStake,
StrategyParams[] memory strategyParams
) external;
/**
* @notice Initialize a new quorum and push its first history update.
* @param quorumNumber The number of the quorum to initialize.
* @param minimumStake The minimum stake required for the quorum.
* @param lookAheadPeriod The look ahead period for checking operator shares.
* @param strategyParams The initial strategy parameters for the quorum.
*/
function initializeSlashableStakeQuorum(
uint8 quorumNumber,
uint96 minimumStake,
uint32 lookAheadPeriod,
StrategyParams[] memory strategyParams
) external;
/**
* @notice Sets the minimum stake requirement for a quorum `quorumNumber`.
* @param quorumNumber The quorum number to set the minimum stake for.
* @param minimumStake The new minimum stake requirement.
*/
function setMinimumStakeForQuorum(uint8 quorumNumber, uint96 minimumStake) external;
/**
* @notice Sets the look ahead time to `lookAheadBlocks` for checking operator shares for a specific quorum.
* @param quorumNumber The quorum number to set the look ahead period for.
* @param lookAheadBlocks The number of blocks to look ahead when checking shares.
*/
function setSlashableStakeLookahead(uint8 quorumNumber, uint32 lookAheadBlocks) external;
/**
* @notice Adds new strategies and their associated multipliers to the specified quorum.
* @dev Checks to make sure that the *same* strategy cannot be added multiple times (checks against both against existing and new strategies).
* @dev This function has no check to make sure that the strategies for a single quorum have the same underlying asset. This is a concious choice,
* since a middleware may want, e.g., a stablecoin quorum that accepts USDC, USDT, DAI, etc. as underlying assets and trades them as "equivalent".
* @param quorumNumber The quorum number to add strategies to.
* @param strategyParams The strategy parameters to add.
*/
function addStrategies(uint8 quorumNumber, StrategyParams[] memory strategyParams) external;
/**
* @notice Removes strategies and their associated weights from the specified quorum.
* @param quorumNumber The quorum number to remove strategies from.
* @param indicesToRemove The indices of strategies to remove.
* @dev Higher indices should be *first* in the list of `indicesToRemove`, since otherwise
* the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove.
*/
function removeStrategies(uint8 quorumNumber, uint256[] calldata indicesToRemove) external;
/**
* @notice Modifies the weights of strategies that are already in the mapping strategyParams.
* @param quorumNumber The quorum number to change the strategy for.
* @param strategyIndices The indices of the strategies to change.
* @param newMultipliers The new multipliers for the strategies.
*/
function modifyStrategyParams(
uint8 quorumNumber,
uint256[] calldata strategyIndices,
uint96[] calldata newMultipliers
) external;
/// VIEW
\
Submitted on: 2025-09-30 10:32:43
Comments
Log in to comment.
No comments yet.