From 7cb4449a1af506cce6df2efa904647dc4c0b5311 Mon Sep 17 00:00:00 2001 From: "clandestine.eth" <96172957+0xClandestine@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:29:35 -0500 Subject: [PATCH] refactor: natspec + interfaces refactor: natspec + interfaces docs: `RegistryCoordinator` natspec chore: forge fmt refactor: named mapping params docs: natspec `BLSApkRegistry` docs: natspec `BLSApkRegistry` docs: natspec `BLSApkRegistry` refactor: interface structure refactor: separate `BLSSignatureChecker` storage refactor: rename -> `IECDSAStakeRegistry` docs: natspec docs: natspec `ECDSAStakeRegistry` docs: natspec `EjectionManager` + separate storage docs: natspec docs: natspec `IndexRegistry` refactor: remove `IRegistry` chore: forge fmt chore: make storage-report docs: natspec refactor: remove `ISocketUpdater` --- .github/bin/storage-report.sh | 2 +- bin/storage-report.sh | 2 +- docs/RegistryCoordinator.md | 6 +- docs/storage-report/BLSApkRegistry.md | 38 +- docs/storage-report/BLSApkRegistryStorage.md | 38 +- .../BLSSignatureCheckerStorage.md | 9 + docs/storage-report/ECDSAStakeRegistry.md | 2 +- .../ECDSAStakeRegistryEqualWeight.md | 2 +- .../ECDSAStakeRegistryPermissioned.md | 2 +- .../ECDSAStakeRegistryStorage.md | 2 +- docs/storage-report/EjectionManager.md | 38 +- docs/storage-report/EjectionManagerStorage.md | 11 + docs/storage-report/IndexRegistry.md | 30 +- docs/storage-report/IndexRegistryStorage.md | 30 +- docs/storage-report/RegistryCoordinator.md | 94 +-- .../RegistryCoordinatorStorage.md | 62 +- docs/storage-report/StakeRegistry.md | 38 +- docs/storage-report/StakeRegistryStorage.md | 38 +- src/BLSApkRegistry.sol | 73 +-- src/BLSApkRegistryStorage.sol | 33 +- src/BLSSignatureChecker.sol | 84 +-- src/BLSSignatureCheckerStorage.sol | 38 ++ src/EjectionManager.sol | 125 ++-- src/EjectionManagerStorage.sol | 30 + src/IndexRegistry.sol | 113 ++-- src/RegistryCoordinator.sol | 223 +++---- src/StakeRegistry.sol | 169 +----- src/StakeRegistryStorage.sol | 6 +- src/interfaces/IBLSApkRegistry.sol | 275 +++++---- src/interfaces/IBLSSignatureChecker.sol | 154 +++-- src/interfaces/IECDSAStakeRegistry.sol | 247 ++++++++ .../IECDSAStakeRegistryEventsAndErrors.sol | 105 ---- src/interfaces/IEjectionManager.sol | 136 +++-- src/interfaces/IIndexRegistry.sol | 168 +++--- src/interfaces/IRegistry.sol | 13 - src/interfaces/IRegistryCoordinator.sol | 547 ++++++++++++++---- src/interfaces/IServiceManager.sol | 102 ++-- src/interfaces/IServiceManagerUI.sol | 68 +-- src/interfaces/ISlasher.sol | 78 ++- src/interfaces/ISocketUpdater.sol | 22 - src/interfaces/IStakeRegistry.sol | 400 +++++++------ src/libraries/QuorumBitmapHistoryLib.sol | 8 +- src/unaudited/ECDSAServiceManagerBase.sol | 6 +- src/unaudited/ECDSAStakeRegistry.sol | 453 +++++++-------- src/unaudited/ECDSAStakeRegistryStorage.sol | 10 +- test/ffi/BLSPubKeyCompendiumFFI.t.sol | 4 +- test/ffi/UpdateOperators.t.sol | 4 +- test/integration/IntegrationBase.t.sol | 20 +- test/integration/IntegrationConfig.t.sol | 25 +- test/integration/IntegrationDeployer.t.sol | 5 +- test/integration/User.t.sol | 21 +- test/mocks/RegistryCoordinatorMock.sol | 184 ++++-- test/mocks/StakeRegistryMock.sol | 13 + test/unit/BLSSignatureCheckerUnit.t.sol | 9 +- test/unit/ECDSAServiceManager.t.sol | 4 +- .../ECDSAStakeRegistryEqualWeightUnit.t.sol | 10 +- .../ECDSAStakeRegistryPermissionedUnit.t.sol | 15 +- test/unit/ECDSAStakeRegistryUnit.t.sol | 93 +-- test/unit/EjectionManagerUnit.t.sol | 51 +- test/unit/IndexRegistryUnit.t.sol | 2 +- test/unit/OperatorStateRetrieverUnit.t.sol | 28 +- test/unit/RegistryCoordinatorUnit.t.sol | 320 +++++----- test/unit/StakeRegistryUnit.t.sol | 115 ++-- test/utils/MockAVSDeployer.sol | 22 +- 64 files changed, 2789 insertions(+), 2286 deletions(-) create mode 100644 docs/storage-report/BLSSignatureCheckerStorage.md create mode 100644 docs/storage-report/EjectionManagerStorage.md create mode 100644 src/BLSSignatureCheckerStorage.sol create mode 100644 src/EjectionManagerStorage.sol create mode 100644 src/interfaces/IECDSAStakeRegistry.sol delete mode 100644 src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol delete mode 100644 src/interfaces/IRegistry.sol delete mode 100644 src/interfaces/ISocketUpdater.sol diff --git a/.github/bin/storage-report.sh b/.github/bin/storage-report.sh index 71fbd9a0..4c34d5ac 100644 --- a/.github/bin/storage-report.sh +++ b/.github/bin/storage-report.sh @@ -37,7 +37,7 @@ for file in $(find src/ -name "*.sol" ! -path "*/interfaces/*" ! -path "*/librar log "Processing contract: $contract_name" # Run forge inspect and capture errors - if ! forge inspect "$contract_name" storage --pretty > "$OUTPUT_DIR/$contract_name.md"; then + if ! forge inspect "$contract_name" storage > "$OUTPUT_DIR/$contract_name.md"; then error "Failed to generate storage report for contract: $contract_name" else log "Storage report generated for contract: $contract_name" diff --git a/bin/storage-report.sh b/bin/storage-report.sh index 71fbd9a0..4c34d5ac 100644 --- a/bin/storage-report.sh +++ b/bin/storage-report.sh @@ -37,7 +37,7 @@ for file in $(find src/ -name "*.sol" ! -path "*/interfaces/*" ! -path "*/librar log "Processing contract: $contract_name" # Run forge inspect and capture errors - if ! forge inspect "$contract_name" storage --pretty > "$OUTPUT_DIR/$contract_name.md"; then + if ! forge inspect "$contract_name" storage > "$OUTPUT_DIR/$contract_name.md"; then error "Failed to generate storage report for contract: $contract_name" else log "Storage report generated for contract: $contract_name" diff --git a/docs/RegistryCoordinator.md b/docs/RegistryCoordinator.md index 1f917638..4752c7f7 100644 --- a/docs/RegistryCoordinator.md +++ b/docs/RegistryCoordinator.md @@ -42,7 +42,7 @@ These methods allow operators to register for/deregister from one or more quorum function registerOperator( bytes calldata quorumNumbers, string calldata socket, - IBLSApkRegistry.PubkeyRegistrationParams calldata params, + IBLSApkRegistryTypes.PubkeyRegistrationParams calldata params, SignatureWithSaltAndExpiry memory operatorSignature ) external @@ -88,7 +88,7 @@ If the Operator was not currently registered for any quorums, this method will r function registerOperatorWithChurn( bytes calldata quorumNumbers, string calldata socket, - IBLSApkRegistry.PubkeyRegistrationParams calldata params, + IBLSApkRegistryTypes.PubkeyRegistrationParams calldata params, OperatorKickParam[] calldata operatorKickParams, SignatureWithSaltAndExpiry memory churnApproverSignature, SignatureWithSaltAndExpiry memory operatorSignature @@ -256,7 +256,7 @@ These methods are used by the Owner to configure the `RegistryCoordinator`: function createQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) external virtual diff --git a/docs/storage-report/BLSApkRegistry.md b/docs/storage-report/BLSApkRegistry.md index 69239c7c..cc7dfd66 100644 --- a/docs/storage-report/BLSApkRegistry.md +++ b/docs/storage-report/BLSApkRegistry.md @@ -1,21 +1,21 @@ -╭----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+=============================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| operatorToPubkeyHash | mapping(address => bytes32) | 1 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| pubkeyHashToOperator | mapping(bytes32 => address) | 2 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| operatorToPubkey | mapping(address => struct BN254.G1Point) | 3 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| apkHistory | mapping(uint8 => struct IBLSApkRegistry.ApkUpdate[]) | 4 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| currentApk | mapping(uint8 => struct BN254.G1Point) | 5 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | -|----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------| -| __GAP | uint256[45] | 6 | 0 | 1440 | src/BLSApkRegistry.sol:BLSApkRegistry | -╰----------------------+------------------------------------------------------+------+--------+-------+---------------------------------------╯ +╭----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++==================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| operatorToPubkeyHash | mapping(address => bytes32) | 1 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| pubkeyHashToOperator | mapping(bytes32 => address) | 2 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| operatorToPubkey | mapping(address => struct BN254.G1Point) | 3 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| apkHistory | mapping(uint8 => struct IBLSApkRegistryTypes.ApkUpdate[]) | 4 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| currentApk | mapping(uint8 => struct BN254.G1Point) | 5 | 0 | 32 | src/BLSApkRegistry.sol:BLSApkRegistry | +|----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------| +| __GAP | uint256[45] | 6 | 0 | 1440 | src/BLSApkRegistry.sol:BLSApkRegistry | +╰----------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------╯ diff --git a/docs/storage-report/BLSApkRegistryStorage.md b/docs/storage-report/BLSApkRegistryStorage.md index 3b5b9e61..57e7bf28 100644 --- a/docs/storage-report/BLSApkRegistryStorage.md +++ b/docs/storage-report/BLSApkRegistryStorage.md @@ -1,21 +1,21 @@ -╭----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+===========================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| operatorToPubkeyHash | mapping(address => bytes32) | 1 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| pubkeyHashToOperator | mapping(bytes32 => address) | 2 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| operatorToPubkey | mapping(address => struct BN254.G1Point) | 3 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| apkHistory | mapping(uint8 => struct IBLSApkRegistry.ApkUpdate[]) | 4 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| currentApk | mapping(uint8 => struct BN254.G1Point) | 5 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -|----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------| -| __GAP | uint256[45] | 6 | 0 | 1440 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | -╰----------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------╯ +╭----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| operatorToPubkeyHash | mapping(address => bytes32) | 1 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| pubkeyHashToOperator | mapping(bytes32 => address) | 2 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| operatorToPubkey | mapping(address => struct BN254.G1Point) | 3 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| apkHistory | mapping(uint8 => struct IBLSApkRegistryTypes.ApkUpdate[]) | 4 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| currentApk | mapping(uint8 => struct BN254.G1Point) | 5 | 0 | 32 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +|----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------| +| __GAP | uint256[45] | 6 | 0 | 1440 | src/BLSApkRegistryStorage.sol:BLSApkRegistryStorage | +╰----------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------╯ diff --git a/docs/storage-report/BLSSignatureCheckerStorage.md b/docs/storage-report/BLSSignatureCheckerStorage.md new file mode 100644 index 00000000..cf8a54f2 --- /dev/null +++ b/docs/storage-report/BLSSignatureCheckerStorage.md @@ -0,0 +1,9 @@ + +╭----------------------+-------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++============================================================================================================================+ +| staleStakesForbidden | bool | 0 | 0 | 1 | src/BLSSignatureCheckerStorage.sol:BLSSignatureCheckerStorage | +|----------------------+-------------+------+--------+-------+---------------------------------------------------------------| +| __GAP | uint256[49] | 1 | 0 | 1568 | src/BLSSignatureCheckerStorage.sol:BLSSignatureCheckerStorage | +╰----------------------+-------------+------+--------+-------+---------------------------------------------------------------╯ + diff --git a/docs/storage-report/ECDSAStakeRegistry.md b/docs/storage-report/ECDSAStakeRegistry.md index df768c27..8f9200d4 100644 --- a/docs/storage-report/ECDSAStakeRegistry.md +++ b/docs/storage-report/ECDSAStakeRegistry.md @@ -14,7 +14,7 @@ |----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| | _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | |----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | +| _quorum | struct IECDSAStakeRegistryTypes.Quorum | 102 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | |----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| | _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | |----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| diff --git a/docs/storage-report/ECDSAStakeRegistryEqualWeight.md b/docs/storage-report/ECDSAStakeRegistryEqualWeight.md index e1e1c166..fbd09d32 100644 --- a/docs/storage-report/ECDSAStakeRegistryEqualWeight.md +++ b/docs/storage-report/ECDSAStakeRegistryEqualWeight.md @@ -14,7 +14,7 @@ |----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| | _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | |----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | +| _quorum | struct IECDSAStakeRegistryTypes.Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | |----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| | _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | |----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| diff --git a/docs/storage-report/ECDSAStakeRegistryPermissioned.md b/docs/storage-report/ECDSAStakeRegistryPermissioned.md index bdc5b32e..bc9ae389 100644 --- a/docs/storage-report/ECDSAStakeRegistryPermissioned.md +++ b/docs/storage-report/ECDSAStakeRegistryPermissioned.md @@ -14,7 +14,7 @@ |----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| | _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | |----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | +| _quorum | struct IECDSAStakeRegistryTypes.Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | |----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| | _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | |----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| diff --git a/docs/storage-report/ECDSAStakeRegistryStorage.md b/docs/storage-report/ECDSAStakeRegistryStorage.md index 69ef3d05..82ca4546 100644 --- a/docs/storage-report/ECDSAStakeRegistryStorage.md +++ b/docs/storage-report/ECDSAStakeRegistryStorage.md @@ -4,7 +4,7 @@ +========================================================================================================================================================================================+ | _totalOperators | uint256 | 0 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | |----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _quorum | struct Quorum | 1 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | +| _quorum | struct IECDSAStakeRegistryTypes.Quorum | 1 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | |----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| | _minimumWeight | uint256 | 2 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | |----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| diff --git a/docs/storage-report/EjectionManager.md b/docs/storage-report/EjectionManager.md index 55e2a2df..2e157da4 100644 --- a/docs/storage-report/EjectionManager.md +++ b/docs/storage-report/EjectionManager.md @@ -1,21 +1,21 @@ -╭-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+==========================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| __gap | uint256[50] | 1 | 0 | 1600 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| _owner | address | 51 | 0 | 20 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| __gap | uint256[49] | 52 | 0 | 1568 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| isEjector | mapping(address => bool) | 101 | 0 | 32 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| stakeEjectedForQuorum | mapping(uint8 => struct IEjectionManager.StakeEjection[]) | 102 | 0 | 32 | src/EjectionManager.sol:EjectionManager | -|-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------| -| quorumEjectionParams | mapping(uint8 => struct IEjectionManager.QuorumEjectionParams) | 103 | 0 | 32 | src/EjectionManager.sol:EjectionManager | -╰-----------------------+----------------------------------------------------------------+------+--------+-------+-----------------------------------------╯ +╭-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++===============================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| __gap | uint256[50] | 1 | 0 | 1600 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| _owner | address | 51 | 0 | 20 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| __gap | uint256[49] | 52 | 0 | 1568 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| isEjector | mapping(address => bool) | 101 | 0 | 32 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| stakeEjectedForQuorum | mapping(uint8 => struct IEjectionManagerTypes.StakeEjection[]) | 102 | 0 | 32 | src/EjectionManager.sol:EjectionManager | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------| +| quorumEjectionParams | mapping(uint8 => struct IEjectionManagerTypes.QuorumEjectionParams) | 103 | 0 | 32 | src/EjectionManager.sol:EjectionManager | +╰-----------------------+---------------------------------------------------------------------+------+--------+-------+-----------------------------------------╯ diff --git a/docs/storage-report/EjectionManagerStorage.md b/docs/storage-report/EjectionManagerStorage.md new file mode 100644 index 00000000..0285800d --- /dev/null +++ b/docs/storage-report/EjectionManagerStorage.md @@ -0,0 +1,11 @@ + +╭-----------------------+---------------------------------------------------------------------+------+--------+-------+-------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++=============================================================================================================================================================================+ +| isEjector | mapping(address => bool) | 0 | 0 | 32 | src/EjectionManagerStorage.sol:EjectionManagerStorage | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-------------------------------------------------------| +| stakeEjectedForQuorum | mapping(uint8 => struct IEjectionManagerTypes.StakeEjection[]) | 1 | 0 | 32 | src/EjectionManagerStorage.sol:EjectionManagerStorage | +|-----------------------+---------------------------------------------------------------------+------+--------+-------+-------------------------------------------------------| +| quorumEjectionParams | mapping(uint8 => struct IEjectionManagerTypes.QuorumEjectionParams) | 2 | 0 | 32 | src/EjectionManagerStorage.sol:EjectionManagerStorage | +╰-----------------------+---------------------------------------------------------------------+------+--------+-------+-------------------------------------------------------╯ + diff --git a/docs/storage-report/IndexRegistry.md b/docs/storage-report/IndexRegistry.md index 3415bdcd..526d85d1 100644 --- a/docs/storage-report/IndexRegistry.md +++ b/docs/storage-report/IndexRegistry.md @@ -1,17 +1,17 @@ -╭-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+===================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/IndexRegistry.sol:IndexRegistry | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/IndexRegistry.sol:IndexRegistry | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| currentOperatorIndex | mapping(uint8 => mapping(bytes32 => uint32)) | 1 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| _operatorIndexHistory | mapping(uint8 => mapping(uint32 => struct IIndexRegistry.OperatorUpdate[])) | 2 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| _operatorCountHistory | mapping(uint8 => struct IIndexRegistry.QuorumUpdate[]) | 3 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| __GAP | uint256[47] | 4 | 0 | 1504 | src/IndexRegistry.sol:IndexRegistry | -╰-----------------------+-----------------------------------------------------------------------------+------+--------+-------+-------------------------------------╯ +╭-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++========================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/IndexRegistry.sol:IndexRegistry | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/IndexRegistry.sol:IndexRegistry | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| currentOperatorIndex | mapping(uint8 => mapping(bytes32 => uint32)) | 1 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| _operatorIndexHistory | mapping(uint8 => mapping(uint32 => struct IIndexRegistryTypes.OperatorUpdate[])) | 2 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| _operatorCountHistory | mapping(uint8 => struct IIndexRegistryTypes.QuorumUpdate[]) | 3 | 0 | 32 | src/IndexRegistry.sol:IndexRegistry | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| __GAP | uint256[47] | 4 | 0 | 1504 | src/IndexRegistry.sol:IndexRegistry | +╰-----------------------+----------------------------------------------------------------------------------+------+--------+-------+-------------------------------------╯ diff --git a/docs/storage-report/IndexRegistryStorage.md b/docs/storage-report/IndexRegistryStorage.md index 9581f514..a30c1362 100644 --- a/docs/storage-report/IndexRegistryStorage.md +++ b/docs/storage-report/IndexRegistryStorage.md @@ -1,17 +1,17 @@ -╭-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+=================================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| currentOperatorIndex | mapping(uint8 => mapping(bytes32 => uint32)) | 1 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| _operatorIndexHistory | mapping(uint8 => mapping(uint32 => struct IIndexRegistry.OperatorUpdate[])) | 2 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| _operatorCountHistory | mapping(uint8 => struct IIndexRegistry.QuorumUpdate[]) | 3 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -|-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| __GAP | uint256[47] | 4 | 0 | 1504 | src/IndexRegistryStorage.sol:IndexRegistryStorage | -╰-----------------------+-----------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╯ +╭-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++======================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| currentOperatorIndex | mapping(uint8 => mapping(bytes32 => uint32)) | 1 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| _operatorIndexHistory | mapping(uint8 => mapping(uint32 => struct IIndexRegistryTypes.OperatorUpdate[])) | 2 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| _operatorCountHistory | mapping(uint8 => struct IIndexRegistryTypes.QuorumUpdate[]) | 3 | 0 | 32 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +|-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| __GAP | uint256[47] | 4 | 0 | 1504 | src/IndexRegistryStorage.sol:IndexRegistryStorage | +╰-----------------------+----------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╯ diff --git a/docs/storage-report/RegistryCoordinator.md b/docs/storage-report/RegistryCoordinator.md index 1adff5f4..edae4c10 100644 --- a/docs/storage-report/RegistryCoordinator.md +++ b/docs/storage-report/RegistryCoordinator.md @@ -1,49 +1,49 @@ -╭-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+==============================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| __deprecated_pauserRegistry | contract IPauserRegistry | 0 | 2 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _paused | uint256 | 1 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| __gap | uint256[48] | 2 | 0 | 1536 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| __gap | uint256[50] | 50 | 0 | 1600 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _owner | address | 100 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| __gap | uint256[49] | 101 | 0 | 1568 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| quorumCount | uint8 | 150 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _quorumParams | mapping(uint8 => struct IRegistryCoordinator.OperatorSetParam) | 151 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _operatorBitmapHistory | mapping(bytes32 => struct IRegistryCoordinator.QuorumBitmapUpdate[]) | 152 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| _operatorInfo | mapping(address => struct IRegistryCoordinator.OperatorInfo) | 153 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| isChurnApproverSaltUsed | mapping(bytes32 => bool) | 154 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| quorumUpdateBlockNumber | mapping(uint8 => uint256) | 155 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| registries | address[] | 156 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| churnApprover | address | 157 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| ejector | address | 158 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| lastEjectionTimestamp | mapping(address => uint256) | 159 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| ejectionCooldown | uint256 | 160 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| isOperatorSetAVS | bool | 161 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| isM2Quorum | mapping(uint8 => bool) | 162 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | -|-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| -| __GAP | uint256[37] | 163 | 0 | 1184 | src/RegistryCoordinator.sol:RegistryCoordinator | -╰-----------------------------+----------------------------------------------------------------------+------+--------+-------+-------------------------------------------------╯ +╭-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++===================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _initializing | bool | 0 | 1 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| __deprecated_pauserRegistry | contract IPauserRegistry | 0 | 2 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _paused | uint256 | 1 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| __gap | uint256[48] | 2 | 0 | 1536 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| __gap | uint256[50] | 50 | 0 | 1600 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _owner | address | 100 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| __gap | uint256[49] | 101 | 0 | 1568 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| quorumCount | uint8 | 150 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _quorumParams | mapping(uint8 => struct IRegistryCoordinatorTypes.OperatorSetParam) | 151 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _operatorBitmapHistory | mapping(bytes32 => struct IRegistryCoordinatorTypes.QuorumBitmapUpdate[]) | 152 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| _operatorInfo | mapping(address => struct IRegistryCoordinatorTypes.OperatorInfo) | 153 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| isChurnApproverSaltUsed | mapping(bytes32 => bool) | 154 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| quorumUpdateBlockNumber | mapping(uint8 => uint256) | 155 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| registries | address[] | 156 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| churnApprover | address | 157 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| ejector | address | 158 | 0 | 20 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| lastEjectionTimestamp | mapping(address => uint256) | 159 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| ejectionCooldown | uint256 | 160 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| isOperatorSetAVS | bool | 161 | 0 | 1 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| isM2Quorum | mapping(uint8 => bool) | 162 | 0 | 32 | src/RegistryCoordinator.sol:RegistryCoordinator | +|-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------| +| __GAP | uint256[37] | 163 | 0 | 1184 | src/RegistryCoordinator.sol:RegistryCoordinator | +╰-----------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------------------╯ diff --git a/docs/storage-report/RegistryCoordinatorStorage.md b/docs/storage-report/RegistryCoordinatorStorage.md index 1e9fc25d..655447c6 100644 --- a/docs/storage-report/RegistryCoordinatorStorage.md +++ b/docs/storage-report/RegistryCoordinatorStorage.md @@ -1,33 +1,33 @@ -╭-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+========================================================================================================================================================================================+ -| quorumCount | uint8 | 0 | 0 | 1 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| _quorumParams | mapping(uint8 => struct IRegistryCoordinator.OperatorSetParam) | 1 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| _operatorBitmapHistory | mapping(bytes32 => struct IRegistryCoordinator.QuorumBitmapUpdate[]) | 2 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| _operatorInfo | mapping(address => struct IRegistryCoordinator.OperatorInfo) | 3 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| isChurnApproverSaltUsed | mapping(bytes32 => bool) | 4 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| quorumUpdateBlockNumber | mapping(uint8 => uint256) | 5 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| registries | address[] | 6 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| churnApprover | address | 7 | 0 | 20 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| ejector | address | 8 | 0 | 20 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| lastEjectionTimestamp | mapping(address => uint256) | 9 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| ejectionCooldown | uint256 | 10 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| isOperatorSetAVS | bool | 11 | 0 | 1 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| isM2Quorum | mapping(uint8 => bool) | 12 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| __GAP | uint256[37] | 13 | 0 | 1184 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | -╰-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ +╭-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++=============================================================================================================================================================================================+ +| quorumCount | uint8 | 0 | 0 | 1 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| _quorumParams | mapping(uint8 => struct IRegistryCoordinatorTypes.OperatorSetParam) | 1 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| _operatorBitmapHistory | mapping(bytes32 => struct IRegistryCoordinatorTypes.QuorumBitmapUpdate[]) | 2 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| _operatorInfo | mapping(address => struct IRegistryCoordinatorTypes.OperatorInfo) | 3 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| isChurnApproverSaltUsed | mapping(bytes32 => bool) | 4 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| quorumUpdateBlockNumber | mapping(uint8 => uint256) | 5 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| registries | address[] | 6 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| churnApprover | address | 7 | 0 | 20 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| ejector | address | 8 | 0 | 20 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| lastEjectionTimestamp | mapping(address => uint256) | 9 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| ejectionCooldown | uint256 | 10 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| isOperatorSetAVS | bool | 11 | 0 | 1 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| isM2Quorum | mapping(uint8 => bool) | 12 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| __GAP | uint256[37] | 13 | 0 | 1184 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +╰-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ diff --git a/docs/storage-report/StakeRegistry.md b/docs/storage-report/StakeRegistry.md index 820aaba6..628df515 100644 --- a/docs/storage-report/StakeRegistry.md +++ b/docs/storage-report/StakeRegistry.md @@ -1,21 +1,21 @@ -╭----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+============================================================================================================================================================================+ -| minimumStakeForQuorum | mapping(uint8 => uint96) | 0 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| _totalStakeHistory | mapping(uint8 => struct IStakeRegistry.StakeUpdate[]) | 1 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| operatorStakeHistory | mapping(bytes32 => mapping(uint8 => struct IStakeRegistry.StakeUpdate[])) | 2 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| strategyParams | mapping(uint8 => struct IStakeRegistry.StrategyParams[]) | 3 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| strategiesPerQuorum | mapping(uint8 => contract IStrategy[]) | 4 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| stakeTypePerQuorum | mapping(uint8 => enum StakeType) | 5 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| slashableStakeLookAheadPerQuorum | mapping(uint8 => uint32) | 6 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------| -| __GAP | uint256[43] | 7 | 0 | 1376 | src/StakeRegistry.sol:StakeRegistry | -╰----------------------------------+---------------------------------------------------------------------------+------+--------+-------+-------------------------------------╯ +╭----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++=================================================================================================================================================================================+ +| minimumStakeForQuorum | mapping(uint8 => uint96) | 0 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| _totalStakeHistory | mapping(uint8 => struct IStakeRegistryTypes.StakeUpdate[]) | 1 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| operatorStakeHistory | mapping(bytes32 => mapping(uint8 => struct IStakeRegistryTypes.StakeUpdate[])) | 2 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| strategyParams | mapping(uint8 => struct IStakeRegistryTypes.StrategyParams[]) | 3 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| strategiesPerQuorum | mapping(uint8 => contract IStrategy[]) | 4 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| stakeTypePerQuorum | mapping(uint8 => enum IStakeRegistryTypes.StakeType) | 5 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| slashableStakeLookAheadPerQuorum | mapping(uint8 => uint32) | 6 | 0 | 32 | src/StakeRegistry.sol:StakeRegistry | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------| +| __GAP | uint256[43] | 7 | 0 | 1376 | src/StakeRegistry.sol:StakeRegistry | +╰----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+-------------------------------------╯ diff --git a/docs/storage-report/StakeRegistryStorage.md b/docs/storage-report/StakeRegistryStorage.md index 4a545513..92154a7f 100644 --- a/docs/storage-report/StakeRegistryStorage.md +++ b/docs/storage-report/StakeRegistryStorage.md @@ -1,21 +1,21 @@ -╭----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+==========================================================================================================================================================================================+ -| minimumStakeForQuorum | mapping(uint8 => uint96) | 0 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| _totalStakeHistory | mapping(uint8 => struct IStakeRegistry.StakeUpdate[]) | 1 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| operatorStakeHistory | mapping(bytes32 => mapping(uint8 => struct IStakeRegistry.StakeUpdate[])) | 2 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| strategyParams | mapping(uint8 => struct IStakeRegistry.StrategyParams[]) | 3 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| strategiesPerQuorum | mapping(uint8 => contract IStrategy[]) | 4 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| stakeTypePerQuorum | mapping(uint8 => enum StakeType) | 5 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| slashableStakeLookAheadPerQuorum | mapping(uint8 => uint32) | 6 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -|----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| -| __GAP | uint256[43] | 7 | 0 | 1376 | src/StakeRegistryStorage.sol:StakeRegistryStorage | -╰----------------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╯ +╭----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | Contract | ++===============================================================================================================================================================================================+ +| minimumStakeForQuorum | mapping(uint8 => uint96) | 0 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| _totalStakeHistory | mapping(uint8 => struct IStakeRegistryTypes.StakeUpdate[]) | 1 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| operatorStakeHistory | mapping(bytes32 => mapping(uint8 => struct IStakeRegistryTypes.StakeUpdate[])) | 2 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| strategyParams | mapping(uint8 => struct IStakeRegistryTypes.StrategyParams[]) | 3 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| strategiesPerQuorum | mapping(uint8 => contract IStrategy[]) | 4 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| stakeTypePerQuorum | mapping(uint8 => enum IStakeRegistryTypes.StakeType) | 5 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| slashableStakeLookAheadPerQuorum | mapping(uint8 => uint32) | 6 | 0 | 32 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +|----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------| +| __GAP | uint256[43] | 7 | 0 | 1376 | src/StakeRegistryStorage.sol:StakeRegistryStorage | +╰----------------------------------+--------------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------╯ diff --git a/src/BLSApkRegistry.sol b/src/BLSApkRegistry.sol index 93972f5c..17f2df03 100644 --- a/src/BLSApkRegistry.sol +++ b/src/BLSApkRegistry.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {BLSApkRegistryStorage} from "./BLSApkRegistryStorage.sol"; +import {BLSApkRegistryStorage, IBLSApkRegistry} from "./BLSApkRegistryStorage.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; @@ -27,17 +27,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { * */ - /** - * @notice Registers the `operator`'s pubkey for the specified `quorumNumbers`. - * @param operator The address of the operator to register. - * @param quorumNumbers The quorum numbers the operator is registering for, 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 registered - */ + /// @inheritdoc IBLSApkRegistry function registerOperator( address operator, bytes memory quorumNumbers @@ -49,21 +39,10 @@ contract BLSApkRegistry is BLSApkRegistryStorage { _processQuorumApkUpdate(quorumNumbers, pubkey); // Return pubkeyHash, which will become the operator's unique id - emit OperatorAddedToQuorums(operator, getOperatorId(operator), quorumNumbers); + emit OperatorAddedToQuorums(operator, operatorToPubkeyHash[operator], quorumNumbers); } - /** - * @notice Deregisters the `operator`'s pubkey for the specified `quorumNumbers`. - * @param operator The address 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 - */ + /// @inheritdoc IBLSApkRegistry function deregisterOperator( address operator, bytes memory quorumNumbers @@ -73,13 +52,10 @@ contract BLSApkRegistry is BLSApkRegistryStorage { // Update each quorum's aggregate pubkey _processQuorumApkUpdate(quorumNumbers, pubkey.negate()); - emit OperatorRemovedFromQuorums(operator, getOperatorId(operator), quorumNumbers); + emit OperatorRemovedFromQuorums(operator, operatorToPubkeyHash[operator], quorumNumbers); } - /** - * @notice Initializes a new quorum by pushing its first apk update - * @param quorumNumber The number of the new quorum - */ + /// @inheritdoc IBLSApkRegistry function initializeQuorum( uint8 quorumNumber ) public virtual onlyRegistryCoordinator { @@ -94,12 +70,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { ); } - /** - * @notice Called by the RegistryCoordinator register an operator as the owner of a BLS public key. - * @param operator is the operator for whom the key is being registered - * @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership - * @param pubkeyRegistrationMessageHash is a hash that the operator must sign to prove key ownership - */ + /// @inheritdoc IBLSApkRegistry function registerBLSPublicKey( address operator, PubkeyRegistrationParams calldata params, @@ -190,10 +161,8 @@ contract BLSApkRegistry is BLSApkRegistryStorage { * VIEW FUNCTIONS * */ - /** - * @notice Returns the pubkey and pubkey hash of an operator - * @dev Reverts if the operator has not registered a valid pubkey - */ + + /// @inheritdoc IBLSApkRegistry function getRegisteredPubkey( address operator ) public view returns (BN254.G1Point memory, bytes32) { @@ -205,10 +174,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { return (pubkey, pubkeyHash); } - /** - * @notice Returns the indices of the quorumApks index at `blockNumber` for the provided `quorumNumbers` - * @dev Returns the current indices if `blockNumber >= block.number` - */ + /// @inheritdoc IBLSApkRegistry function getApkIndicesAtBlockNumber( bytes calldata quorumNumbers, uint256 blockNumber @@ -239,14 +205,14 @@ contract BLSApkRegistry is BLSApkRegistryStorage { return indices; } - /// @notice Returns the current APK for the provided `quorumNumber ` + /// @inheritdoc IBLSApkRegistry function getApk( uint8 quorumNumber ) external view returns (BN254.G1Point memory) { return currentApk[quorumNumber]; } - /// @notice Returns the `ApkUpdate` struct at `index` in the list of APK updates for the `quorumNumber` + /// @inheritdoc IBLSApkRegistry function getApkUpdateAtIndex( uint8 quorumNumber, uint256 index @@ -254,13 +220,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { return apkHistory[quorumNumber][index]; } - /** - * @notice get hash of the apk of `quorumNumber` at `blockNumber` using the provided `index`; - * called by checkSignatures in BLSSignatureChecker.sol. - * @param quorumNumber is the quorum whose ApkHash is being retrieved - * @param blockNumber is the number of the block for which the latest ApkHash will be retrieved - * @param index is the index of the apkUpdate being retrieved from the list of quorum apkUpdates in storage - */ + /// @inheritdoc IBLSApkRegistry function getApkHashAtBlockNumberAndIndex( uint8 quorumNumber, uint32 blockNumber, @@ -283,22 +243,21 @@ contract BLSApkRegistry is BLSApkRegistryStorage { return quorumApkUpdate.apkHash; } - /// @notice Returns the length of ApkUpdates for the provided `quorumNumber` + /// @inheritdoc IBLSApkRegistry function getApkHistoryLength( uint8 quorumNumber ) external view returns (uint32) { return uint32(apkHistory[quorumNumber].length); } - /// @notice Returns the operator address for the given `pubkeyHash` + /// @inheritdoc IBLSApkRegistry function getOperatorFromPubkeyHash( bytes32 pubkeyHash ) public view returns (address) { return pubkeyHashToOperator[pubkeyHash]; } - /// @notice returns the ID used to identify the `operator` within this AVS - /// @dev Returns zero in the event that the `operator` has never registered for the AVS + /// @inheritdoc IBLSApkRegistry function getOperatorId( address operator ) public view returns (bytes32) { diff --git a/src/BLSApkRegistryStorage.sol b/src/BLSApkRegistryStorage.sol index 5007367a..35d0ac31 100644 --- a/src/BLSApkRegistryStorage.sol +++ b/src/BLSApkRegistryStorage.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; +import {IBLSApkRegistry, IBLSApkRegistryTypes} from "./interfaces/IBLSApkRegistry.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; @@ -9,26 +9,28 @@ import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initia import {BN254} from "./libraries/BN254.sol"; abstract contract BLSApkRegistryStorage is Initializable, IBLSApkRegistry { - /// @notice the hash of the zero pubkey aka BN254.G1Point(0,0) + /// @dev Returns the hash of the zero pubkey aka BN254.G1Point(0,0) bytes32 internal constant ZERO_PK_HASH = hex"ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5"; - /// @notice the registry coordinator contract + /// @inheritdoc IBLSApkRegistry address public immutable registryCoordinator; - // storage for individual pubkeys - /// @notice maps operator address to pubkey hash - mapping(address => bytes32) public operatorToPubkeyHash; - /// @notice maps pubkey hash to operator address - mapping(bytes32 => address) public pubkeyHashToOperator; - /// @notice maps operator address to pubkeyG1 - mapping(address => BN254.G1Point) public operatorToPubkey; + /// INDIVIDUAL PUBLIC KEY STORAGE - // storage for aggregate pubkeys (APKs) - /// @notice maps quorumNumber => historical aggregate pubkey updates - mapping(uint8 => ApkUpdate[]) public apkHistory; - /// @notice maps quorumNumber => current aggregate pubkey of quorum - mapping(uint8 => BN254.G1Point) public currentApk; + /// @inheritdoc IBLSApkRegistry + mapping(address operator => bytes32 operatorId) public operatorToPubkeyHash; + /// @inheritdoc IBLSApkRegistry + mapping(bytes32 pubkeyHash => address operator) public pubkeyHashToOperator; + /// @inheritdoc IBLSApkRegistry + mapping(address operator => BN254.G1Point pubkeyG1) public operatorToPubkey; + + /// AGGREGATE PUBLIC KEY STORAGE + + /// @inheritdoc IBLSApkRegistry + mapping(uint8 quorumNumber => IBLSApkRegistryTypes.ApkUpdate[]) public apkHistory; + /// @inheritdoc IBLSApkRegistry + mapping(uint8 quorumNumber => BN254.G1Point) public currentApk; constructor( IRegistryCoordinator _registryCoordinator @@ -38,6 +40,5 @@ abstract contract BLSApkRegistryStorage is Initializable, IBLSApkRegistry { _disableInitializers(); } - // storage gap for upgradeability uint256[45] private __GAP; } diff --git a/src/BLSSignatureChecker.sol b/src/BLSSignatureChecker.sol index 2ff55e37..df336e86 100644 --- a/src/BLSSignatureChecker.sol +++ b/src/BLSSignatureChecker.sol @@ -1,91 +1,45 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IBLSSignatureChecker} from "./interfaces/IBLSSignatureChecker.sol"; -import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; -import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; -import {IStakeRegistry, IDelegationManager} from "./interfaces/IStakeRegistry.sol"; - import {BitmapUtils} from "./libraries/BitmapUtils.sol"; import {BN254} from "./libraries/BN254.sol"; +import "./BLSSignatureCheckerStorage.sol"; + /** * @title Used for checking BLS aggregate signatures from the operators of a `BLSRegistry`. * @author Layr Labs, Inc. * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service * @notice This is the contract for checking the validity of aggregate operator signatures. */ -contract BLSSignatureChecker is IBLSSignatureChecker { +contract BLSSignatureChecker is BLSSignatureCheckerStorage { using BN254 for BN254.G1Point; - // CONSTANTS & IMMUTABLES - - // gas cost of multiplying 2 pairings - uint256 internal constant PAIRING_EQUALITY_CHECK_GAS = 120_000; - - IRegistryCoordinator public immutable registryCoordinator; - IStakeRegistry public immutable stakeRegistry; - IBLSApkRegistry public immutable blsApkRegistry; - IDelegationManager public immutable delegation; - /// @notice If true, check the staleness of the operator stakes and that its within the delegation withdrawalDelayBlocks window. - bool public staleStakesForbidden; + /// MODIFIERS modifier onlyCoordinatorOwner() { require(msg.sender == registryCoordinator.owner(), OnlyRegistryCoordinatorOwner()); _; } + /// CONSTRUCTION + constructor( IRegistryCoordinator _registryCoordinator - ) { - registryCoordinator = _registryCoordinator; - stakeRegistry = _registryCoordinator.stakeRegistry(); - blsApkRegistry = _registryCoordinator.blsApkRegistry(); - delegation = stakeRegistry.delegation(); - } + ) BLSSignatureCheckerStorage(_registryCoordinator) {} + + /// ACTIONS - /** - * /** - * RegistryCoordinator owner can either enforce or not that operator stakes are staler - * than the delegation.minWithdrawalDelayBlocks() window. - * @param value to toggle staleStakesForbidden - */ + /// @inheritdoc IBLSSignatureChecker function setStaleStakesForbidden( bool value ) external onlyCoordinatorOwner { _setStaleStakesForbidden(value); } - struct NonSignerInfo { - uint256[] quorumBitmaps; - bytes32[] pubkeyHashes; - } + /// VIEW - /** - * @notice This function is called by disperser when it has aggregated all the signatures of the operators - * that are part of the quorum for a particular taskNumber and is asserting them into onchain. The function - * checks that the claim for aggregated signatures are valid. - * - * The thesis of this procedure entails: - * - getting the aggregated pubkey of all registered nodes at the time of pre-commit by the - * disperser (represented by apk in the parameters), - * - subtracting the pubkeys of all the signers not in the quorum (nonSignerPubkeys) and storing - * the output in apk to get aggregated pubkey of all operators that are part of quorum. - * - use this aggregated pubkey to verify the aggregated signature under BLS scheme. - * - * @dev Before signature verification, the function verifies operator stake information. This includes ensuring that the provided `referenceBlockNumber` - * is correct, i.e., ensure that the stake returned from the specified block number is recent enough and that the stake is either the most recent update - * for the total stake (of the operator) or latest before the referenceBlockNumber. - * @param msgHash is the hash being signed - * @dev NOTE: Be careful to ensure `msgHash` is collision-resistant! This method does not hash - * `msgHash` in any way, so if an attacker is able to pass in an arbitrary value, they may be able - * to tamper with signature verification. - * @param quorumNumbers is the bytes array of quorum numbers that are being signed for - * @param referenceBlockNumber is the block number at which the stake information is being verified - * @param params is the struct containing information on nonsigners, stakes, quorum apks, and the aggregate signature - * @return quorumStakeTotals is the struct containing the total and signed stake for each quorum - * @return signatoryRecordHash is the hash of the signatory record, which is used for fraud proofs - */ + /// @inheritdoc IBLSSignatureChecker function checkSignatures( bytes32 msgHash, bytes calldata quorumNumbers, @@ -253,15 +207,7 @@ contract BLSSignatureChecker is IBLSSignatureChecker { return (stakeTotals, signatoryRecordHash); } - /** - * trySignatureAndApkVerification verifies a BLS aggregate signature and the veracity of a calculated G1 Public key - * @param msgHash is the hash being signed - * @param apk is the claimed G1 public key - * @param apkG2 is provided G2 public key - * @param sigma is the G1 point signature - * @return pairingSuccessful is true if the pairing precompile call was successful - * @return siganatureIsValid is true if the signature is valid - */ + /// @inheritdoc IBLSSignatureChecker function trySignatureAndApkVerification( bytes32 msgHash, BN254.G1Point memory apk, @@ -300,8 +246,4 @@ contract BLSSignatureChecker is IBLSSignatureChecker { staleStakesForbidden = value; emit StaleStakesForbiddenUpdate(value); } - - // storage gap for upgradeability - // slither-disable-next-line shadowing-state - uint256[49] private __GAP; } diff --git a/src/BLSSignatureCheckerStorage.sol b/src/BLSSignatureCheckerStorage.sol new file mode 100644 index 00000000..da78e600 --- /dev/null +++ b/src/BLSSignatureCheckerStorage.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.27; + +import {IBLSSignatureChecker} from "./interfaces/IBLSSignatureChecker.sol"; +import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; +import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; +import {IStakeRegistry, IDelegationManager} from "./interfaces/IStakeRegistry.sol"; + +abstract contract BLSSignatureCheckerStorage is IBLSSignatureChecker { + /// @dev Returns the assumed gas cost of multiplying 2 pairings. + uint256 internal constant PAIRING_EQUALITY_CHECK_GAS = 120_000; + + /// @inheritdoc IBLSSignatureChecker + IRegistryCoordinator public immutable registryCoordinator; + /// @inheritdoc IBLSSignatureChecker + IStakeRegistry public immutable stakeRegistry; + /// @inheritdoc IBLSSignatureChecker + IBLSApkRegistry public immutable blsApkRegistry; + /// @inheritdoc IBLSSignatureChecker + IDelegationManager public immutable delegation; + + /// STATE + + /// @inheritdoc IBLSSignatureChecker + bool public staleStakesForbidden; + + constructor( + IRegistryCoordinator _registryCoordinator + ) { + registryCoordinator = _registryCoordinator; + stakeRegistry = _registryCoordinator.stakeRegistry(); + blsApkRegistry = _registryCoordinator.blsApkRegistry(); + delegation = stakeRegistry.delegation(); + } + + // slither-disable-next-line shadowing-state + uint256[49] private __GAP; +} diff --git a/src/EjectionManager.sol b/src/EjectionManager.sol index f7d3d55d..d44d44d2 100644 --- a/src/EjectionManager.sol +++ b/src/EjectionManager.sol @@ -2,72 +2,48 @@ pragma solidity ^0.8.27; import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import {IEjectionManager} from "./interfaces/IEjectionManager.sol"; -import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; -import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol"; +import { + EjectionManagerStorage, + IEjectionManager, + IRegistryCoordinator, + IStakeRegistry +} from "./EjectionManagerStorage.sol"; + +// TODO: double check order of inheritance since we separated storage from logic... /** * @title Used for automated ejection of operators from the RegistryCoordinator under a ratelimit * @author Layr Labs, Inc. */ -contract EjectionManager is IEjectionManager, OwnableUpgradeable { - /// @notice The basis point denominator for the ejectable stake percent - uint16 internal constant BIPS_DENOMINATOR = 10_000; - - /// @notice The max number of quorums - uint8 internal constant MAX_QUORUM_COUNT = 192; - - /// @notice the RegistryCoordinator contract that is the entry point for ejection - IRegistryCoordinator public immutable registryCoordinator; - /// @notice the StakeRegistry contract that keeps track of quorum stake - IStakeRegistry public immutable stakeRegistry; - - /// @notice Addresses permissioned to eject operators under a ratelimit - mapping(address => bool) public isEjector; - - /// @notice Keeps track of the total stake ejected for a quorum - mapping(uint8 => StakeEjection[]) public stakeEjectedForQuorum; - /// @notice Ratelimit parameters for each quorum - mapping(uint8 => QuorumEjectionParams) public quorumEjectionParams; - - constructor(IRegistryCoordinator _registryCoordinator, IStakeRegistry _stakeRegistry) { - registryCoordinator = _registryCoordinator; - stakeRegistry = _stakeRegistry; - +contract EjectionManager is OwnableUpgradeable, EjectionManagerStorage { + constructor( + IRegistryCoordinator _registryCoordinator, + IStakeRegistry _stakeRegistry + ) EjectionManagerStorage(_registryCoordinator, _stakeRegistry) { _disableInitializers(); } - /** - * @param _owner will hold the owner role - * @param _ejectors will hold the ejector role - * @param _quorumEjectionParams are the ratelimit parameters for the quorum at each index - */ function initialize( address _owner, - address[] memory _ejectors, + address[] memory ejectors, QuorumEjectionParams[] memory _quorumEjectionParams ) external initializer { _transferOwnership(_owner); - for (uint8 i = 0; i < _ejectors.length; i++) { - _setEjector(_ejectors[i], true); + for (uint8 i = 0; i < ejectors.length; i++) { + _setEjector(ejectors[i], true); } for (uint8 i = 0; i < _quorumEjectionParams.length; i++) { _setQuorumEjectionParams(i, _quorumEjectionParams[i]); } } - /** - * @notice Ejects operators from the AVSs RegistryCoordinator under a ratelimit - * @param _operatorIds The ids of the operators 'j' to eject for each quorum 'i' - * @dev This function will eject as many operators as possible prioritizing operators at the lower index - * @dev The owner can eject operators without recording of stake ejection - */ + /// @inheritdoc IEjectionManager function ejectOperators( - bytes32[][] memory _operatorIds + bytes32[][] memory operatorIds ) external { require(isEjector[msg.sender] || msg.sender == owner(), OnlyOwnerOrEjector()); - for (uint256 i = 0; i < _operatorIds.length; ++i) { + for (uint256 i = 0; i < operatorIds.length; ++i) { uint8 quorumNumber = uint8(i); uint256 amountEjectable = amountEjectableForQuorum(quorumNumber); @@ -75,9 +51,9 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable { uint32 ejectedOperators; bool ratelimitHit; - for (uint8 j = 0; j < _operatorIds[i].length; ++j) { + for (uint8 j = 0; j < operatorIds[i].length; ++j) { uint256 operatorStake = - stakeRegistry.getCurrentStake(_operatorIds[i][j], quorumNumber); + stakeRegistry.getCurrentStake(operatorIds[i][j], quorumNumber); //if caller is ejector enforce ratelimit if ( @@ -95,11 +71,11 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable { ++ejectedOperators; registryCoordinator.ejectOperator( - registryCoordinator.getOperatorFromId(_operatorIds[i][j]), + registryCoordinator.getOperatorFromId(operatorIds[i][j]), abi.encodePacked(quorumNumber) ); - emit OperatorEjected(_operatorIds[i][j], quorumNumber); + emit OperatorEjected(operatorIds[i][j], quorumNumber); } //record the stake ejected if ejector and ratelimit enforced @@ -113,67 +89,56 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable { } } - /** - * @notice Sets the ratelimit parameters for a quorum - * @param _quorumNumber The quorum number to set the ratelimit parameters for - * @param _quorumEjectionParams The quorum ratelimit parameters to set for the given quorum - */ + /// @inheritdoc IEjectionManager function setQuorumEjectionParams( - uint8 _quorumNumber, + uint8 quorumNumber, QuorumEjectionParams memory _quorumEjectionParams ) external onlyOwner { - _setQuorumEjectionParams(_quorumNumber, _quorumEjectionParams); + _setQuorumEjectionParams(quorumNumber, _quorumEjectionParams); } - /** - * @notice Sets the address permissioned to eject operators under a ratelimit - * @param _ejector The address to permission - * @param _status The status to set for the given address - */ - function setEjector(address _ejector, bool _status) external onlyOwner { - _setEjector(_ejector, _status); + /// @inheritdoc IEjectionManager + function setEjector(address ejector, bool status) external onlyOwner { + _setEjector(ejector, status); } ///@dev internal function to set the quorum ejection params function _setQuorumEjectionParams( - uint8 _quorumNumber, + uint8 quorumNumber, QuorumEjectionParams memory _quorumEjectionParams ) internal { - require(_quorumNumber < MAX_QUORUM_COUNT, MaxQuorumCount()); - quorumEjectionParams[_quorumNumber] = _quorumEjectionParams; + require(quorumNumber < MAX_QUORUM_COUNT, MaxQuorumCount()); + quorumEjectionParams[quorumNumber] = _quorumEjectionParams; emit QuorumEjectionParamsSet( - _quorumNumber, + quorumNumber, _quorumEjectionParams.rateLimitWindow, _quorumEjectionParams.ejectableStakePercent ); } ///@dev internal function to set the ejector - function _setEjector(address _ejector, bool _status) internal { - isEjector[_ejector] = _status; - emit EjectorUpdated(_ejector, _status); + function _setEjector(address ejector, bool status) internal { + isEjector[ejector] = status; + emit EjectorUpdated(ejector, status); } - /** - * @notice Returns the amount of stake that can be ejected for a quorum at the current block.timestamp - * @param _quorumNumber The quorum number to view ejectable stake for - */ + /// @inheritdoc IEjectionManager function amountEjectableForQuorum( - uint8 _quorumNumber + uint8 quorumNumber ) public view returns (uint256) { - uint256 totalEjectable = uint256(quorumEjectionParams[_quorumNumber].ejectableStakePercent) - * uint256(stakeRegistry.getCurrentTotalStake(_quorumNumber)) / uint256(BIPS_DENOMINATOR); + uint256 totalEjectable = uint256(quorumEjectionParams[quorumNumber].ejectableStakePercent) + * uint256(stakeRegistry.getCurrentTotalStake(quorumNumber)) / uint256(BIPS_DENOMINATOR); - if (stakeEjectedForQuorum[_quorumNumber].length == 0) { + if (stakeEjectedForQuorum[quorumNumber].length == 0) { return totalEjectable; } - uint256 cutoffTime = block.timestamp - quorumEjectionParams[_quorumNumber].rateLimitWindow; + uint256 cutoffTime = block.timestamp - quorumEjectionParams[quorumNumber].rateLimitWindow; uint256 totalEjected = 0; - uint256 i = stakeEjectedForQuorum[_quorumNumber].length - 1; + uint256 i = stakeEjectedForQuorum[quorumNumber].length - 1; - while (stakeEjectedForQuorum[_quorumNumber][i].timestamp > cutoffTime) { - totalEjected += stakeEjectedForQuorum[_quorumNumber][i].stakeEjected; + while (stakeEjectedForQuorum[quorumNumber][i].timestamp > cutoffTime) { + totalEjected += stakeEjectedForQuorum[quorumNumber][i].stakeEjected; if (i == 0) { break; } else { diff --git a/src/EjectionManagerStorage.sol b/src/EjectionManagerStorage.sol new file mode 100644 index 00000000..2badd5ae --- /dev/null +++ b/src/EjectionManagerStorage.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; +import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol"; +import {IEjectionManager} from "./interfaces/IEjectionManager.sol"; + +abstract contract EjectionManagerStorage is IEjectionManager { + /// @notice The basis point denominator for the ejectable stake percent + uint16 internal constant BIPS_DENOMINATOR = 10_000; + /// @notice The max number of quorums + uint8 internal constant MAX_QUORUM_COUNT = 192; + + /// @inheritdoc IEjectionManager + IRegistryCoordinator public immutable registryCoordinator; + /// @inheritdoc IEjectionManager + IStakeRegistry public immutable stakeRegistry; + + /// @inheritdoc IEjectionManager + mapping(address => bool) public isEjector; + /// @inheritdoc IEjectionManager + mapping(uint8 => StakeEjection[]) public stakeEjectedForQuorum; + /// @inheritdoc IEjectionManager + mapping(uint8 => QuorumEjectionParams) public quorumEjectionParams; + + constructor(IRegistryCoordinator _registryCoordinator, IStakeRegistry _stakeRegistry) { + registryCoordinator = _registryCoordinator; + stakeRegistry = _stakeRegistry; + } +} diff --git a/src/IndexRegistry.sol b/src/IndexRegistry.sol index c8b46061..62c1f7ac 100644 --- a/src/IndexRegistry.sol +++ b/src/IndexRegistry.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IndexRegistryStorage} from "./IndexRegistryStorage.sol"; +import {IIndexRegistry, IndexRegistryStorage} from "./IndexRegistryStorage.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; /** @@ -9,13 +9,11 @@ import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; * @author Layr Labs, Inc. */ contract IndexRegistry is IndexRegistryStorage { - /// @notice when applied to a function, only allows the RegistryCoordinator to call it modifier onlyRegistryCoordinator() { _checkRegistryCoordinator(); _; } - /// @notice sets the (immutable) `registryCoordinator` address constructor( IRegistryCoordinator _registryCoordinator ) IndexRegistryStorage(_registryCoordinator) {} @@ -26,18 +24,7 @@ contract IndexRegistry is IndexRegistryStorage { * */ - /** - * @notice Registers the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. - * @param operatorId is the id of the operator that is being registered - * @param quorumNumbers is the quorum numbers the operator is registered for - * @return numOperatorsPerQuorum is a list of the number of operators (including the registering operator) in each of the quorums the operator is registered for - * @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 - */ + /// @inheritdoc IIndexRegistry function registerOperator( bytes32 operatorId, bytes calldata quorumNumbers @@ -68,18 +55,7 @@ contract IndexRegistry is IndexRegistryStorage { return numOperatorsPerQuorum; } - /** - * @notice Deregisters the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. - * @param operatorId is the id of the operator that is being deregistered - * @param quorumNumbers is the quorum numbers the operator is deregistered for - * @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 - */ + /// @inheritdoc IIndexRegistry function deregisterOperator( bytes32 operatorId, bytes calldata quorumNumbers @@ -109,10 +85,7 @@ contract IndexRegistry is IndexRegistryStorage { } } - /** - * @notice Initialize a quorum by pushing its first quorum update - * @param quorumNumber The number of the new quorum - */ + /// @inheritdoc IIndexRegistry function initializeQuorum( uint8 quorumNumber ) public virtual onlyRegistryCoordinator { @@ -129,9 +102,7 @@ contract IndexRegistry is IndexRegistryStorage { * */ - /** - * @notice Increases the historical operator count by 1 and returns the new count - */ + /// @notice Increases the historical operator count by 1 and returns the new count. function _increaseOperatorCount( uint8 quorumNumber ) internal returns (uint32) { @@ -154,9 +125,7 @@ contract IndexRegistry is IndexRegistryStorage { return newOperatorCount; } - /** - * @notice Decreases the historical operator count by 1 and returns the new count - */ + /// @notice Decreases the historical operator count by 1 and returns the new count. function _decreaseOperatorCount( uint8 quorumNumber ) internal returns (uint32) { @@ -168,11 +137,9 @@ contract IndexRegistry is IndexRegistryStorage { return newOperatorCount; } - /** - * @notice Update `_operatorCountHistory` with a new operator count - * @dev If the lastUpdate was made in the this block, update the entry. - * Otherwise, push a new historical entry. - */ + /// @notice Updates `_operatorCountHistory` with a new operator count. + /// @dev If the lastUpdate was made in this block, update the entry. + /// Otherwise, push a new historical entry. function _updateOperatorCountHistory( uint8 quorumNumber, QuorumUpdate storage lastUpdate, @@ -187,11 +154,9 @@ contract IndexRegistry is IndexRegistryStorage { } } - /** - * @notice For a given quorum and operatorIndex, pop and return the last operatorId in the history - * @dev The last entry's operatorId is updated to OPERATOR_DOES_NOT_EXIST_ID - * @return The removed operatorId - */ + /// @notice For a given quorum and operatorIndex, pop and return the last operatorId in the history. + /// @dev The last entry's operatorId is updated to OPERATOR_DOES_NOT_EXIST_ID. + /// @return The removed operatorId. function _popLastOperator( uint8 quorumNumber, uint32 operatorIndex @@ -207,12 +172,10 @@ contract IndexRegistry is IndexRegistryStorage { return removedOperatorId; } - /** - * @notice Assign an operator to an index and update the index history - * @param operatorId operatorId of the operator to update - * @param quorumNumber quorumNumber of the operator to update - * @param operatorIndex the latest index of that operator in the list of operators registered for this quorum - */ + /// @notice Assigns an operator to an index and updates the index history. + /// @param operatorId operatorId of the operator to update. + /// @param quorumNumber quorumNumber of the operator to update. + /// @param operatorIndex the latest index of that operator in the list of operators registered for this quorum. function _assignOperatorToIndex( bytes32 operatorId, uint8 quorumNumber, @@ -227,11 +190,9 @@ contract IndexRegistry is IndexRegistryStorage { emit QuorumIndexUpdate(operatorId, quorumNumber, operatorIndex); } - /** - * @notice Update `_operatorIndexHistory` with a new operator id for the current block - * @dev If the lastUpdate was made in the this block, update the entry. - * Otherwise, push a new historical entry. - */ + /// @notice Updates `_operatorIndexHistory` with a new operator id for the current block. + /// @dev If the lastUpdate was made in this block, update the entry. + /// Otherwise, push a new historical entry. function _updateOperatorIndexHistory( uint8 quorumNumber, uint32 operatorIndex, @@ -247,8 +208,8 @@ contract IndexRegistry is IndexRegistryStorage { } } - /// @notice Returns the most recent operator count update for a quorum - /// @dev Reverts if the quorum does not exist (history length == 0) + /// @notice Returns the most recent operator count update for a quorum. + /// @dev Reverts if the quorum does not exist (history length == 0). function _latestQuorumUpdate( uint8 quorumNumber ) internal view returns (QuorumUpdate storage) { @@ -256,8 +217,8 @@ contract IndexRegistry is IndexRegistryStorage { return _operatorCountHistory[quorumNumber][historyLength - 1]; } - /// @notice Returns the most recent operator id update for an index - /// @dev Reverts if the index has never been used (history length == 0) + /// @notice Returns the most recent operator id update for an index. + /// @dev Reverts if the index has never been used (history length == 0). function _latestOperatorIndexUpdate( uint8 quorumNumber, uint32 operatorIndex @@ -266,10 +227,8 @@ contract IndexRegistry is IndexRegistryStorage { return _operatorIndexHistory[quorumNumber][operatorIndex][historyLength - 1]; } - /** - * @notice Returns the total number of operators of the service for the given `quorumNumber` at the given `blockNumber` - * @dev Reverts if the quorum does not exist, or if the blockNumber is from before the quorum existed - */ + /// @notice Returns the total number of operators of the service for the given `quorumNumber` at the given `blockNumber`. + /// @dev Reverts if the quorum does not exist, or if the blockNumber is from before the quorum existed. function _operatorCountAtBlockNumber( uint8 quorumNumber, uint32 blockNumber @@ -290,10 +249,8 @@ contract IndexRegistry is IndexRegistryStorage { ); } - /** - * @return operatorId at the given `operatorIndex` at the given `blockNumber` for the given `quorumNumber` - * Precondition: requires that the operatorIndex was used active at the given block number for quorum - */ + /// @notice Returns the operatorId at the given `operatorIndex` at the given `blockNumber` for the given `quorumNumber`. + /// @dev Requires that the operatorIndex was active at the given block number for quorum. function _operatorIdForIndexAtBlockNumber( uint8 quorumNumber, uint32 operatorIndex, @@ -322,8 +279,7 @@ contract IndexRegistry is IndexRegistryStorage { * */ - /// @notice Returns the _operatorIndexHistory entry for the specified `operatorIndex` and `quorumNumber` - /// at the specified `arrayIndex` + /// @inheritdoc IIndexRegistry function getOperatorUpdateAtIndex( uint8 quorumNumber, uint32 operatorIndex, @@ -332,7 +288,7 @@ contract IndexRegistry is IndexRegistryStorage { return _operatorIndexHistory[quorumNumber][operatorIndex][arrayIndex]; } - /// @notice Returns the _operatorCountHistory entry for the specified `quorumNumber` at the specified `quorumIndex` + /// @inheritdoc IIndexRegistry function getQuorumUpdateAtIndex( uint8 quorumNumber, uint32 quorumIndex @@ -340,16 +296,14 @@ contract IndexRegistry is IndexRegistryStorage { return _operatorCountHistory[quorumNumber][quorumIndex]; } - /// @notice Returns the most recent QuorumUpdate entry for the specified quorumNumber - /// @dev Reverts if the quorum does not exist + /// @inheritdoc IIndexRegistry function getLatestQuorumUpdate( uint8 quorumNumber ) external view returns (QuorumUpdate memory) { return _latestQuorumUpdate(quorumNumber); } - /// @notice Returns the most recent OperatorUpdate entry for the specified quorumNumber and operatorIndex - /// @dev Reverts if there is no update for the given operatorIndex + /// @inheritdoc IIndexRegistry function getLatestOperatorUpdate( uint8 quorumNumber, uint32 operatorIndex @@ -357,7 +311,7 @@ contract IndexRegistry is IndexRegistryStorage { return _latestOperatorIndexUpdate(quorumNumber, operatorIndex); } - /// @notice Returns an ordered list of operators of the services for the given `quorumNumber` at the given `blockNumber` + /// @inheritdoc IIndexRegistry function getOperatorListAtBlockNumber( uint8 quorumNumber, uint32 blockNumber @@ -371,8 +325,7 @@ contract IndexRegistry is IndexRegistryStorage { return operatorList; } - /// @notice Returns the total number of operators for a given `quorumNumber` - /// @dev This will revert if the quorum does not exist + /// @inheritdoc IIndexRegistry function totalOperatorsForQuorum( uint8 quorumNumber ) external view returns (uint32) { diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 7b906a70..af65140e 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -9,9 +9,8 @@ import { OperatorSet, IAllocationManagerTypes } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; -import {ISocketUpdater} from "./interfaces/ISocketUpdater.sol"; -import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; -import {IStakeRegistry, StakeType} from "./interfaces/IStakeRegistry.sol"; +import {IBLSApkRegistry, IBLSApkRegistryTypes} from "./interfaces/IBLSApkRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./interfaces/IStakeRegistry.sol"; import {IIndexRegistry} from "./interfaces/IIndexRegistry.sol"; import {IServiceManager} from "./interfaces/IServiceManager.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; @@ -45,7 +44,6 @@ contract RegistryCoordinator is OwnableUpgradeable, RegistryCoordinatorStorage, AVSRegistrar, - ISocketUpdater, ISignatureUtils { using BitmapUtils for *; @@ -86,16 +84,7 @@ contract RegistryCoordinator is _disableInitializers(); } - /** - * @param _initialOwner will hold the owner role - * @param _churnApprover will hold the churnApprover role, which authorizes registering with churn - * @param _ejector will hold the ejector role, which can force-eject operators from quorums - * @param _initialPausedStatus pause status after calling initialize - * Config for initial quorums (see `createQuorum`): - * @param _operatorSetParams max operator count and operator churn parameters - * @param _minimumStakes minimum stake weight to allow an operator to register - * @param _strategyParams which Strategies/multipliers a quorum considers when calculating stake weight - */ + /// @inheritdoc IRegistryCoordinator function initialize( address _initialOwner, address _churnApprover, @@ -103,8 +92,8 @@ contract RegistryCoordinator is uint256 _initialPausedStatus, OperatorSetParam[] memory _operatorSetParams, uint96[] memory _minimumStakes, - IStakeRegistry.StrategyParams[][] memory _strategyParams, - StakeType[] memory _stakeTypes, + IStakeRegistryTypes.StrategyParams[][] memory _strategyParams, + IStakeRegistryTypes.StakeType[] memory _stakeTypes, uint32[] memory _lookAheadPeriods ) external initializer { require( @@ -144,20 +133,11 @@ contract RegistryCoordinator is * */ - /** - * @notice Registers msg.sender as an operator for one or more quorums. If any quorum exceeds its maximum - * operator capacity after the operator is registered, this method will fail. - * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for - * @param socket is the socket of the operator (typically an IP address) - * @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership - * @param operatorSignature is the signature of the operator used by the AVS to register the operator in the delegation manager - * @dev `params` is ignored if the caller has previously registered a public key - * @dev `operatorSignature` is ignored if the operator's status is already REGISTERED - */ + /// @inheritdoc IRegistryCoordinator function registerOperator( bytes memory quorumNumbers, string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, SignatureWithSaltAndExpiry memory operatorSignature ) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) { require(!isUsingOperatorSets(), OperatorSetsEnabled()); @@ -192,22 +172,11 @@ contract RegistryCoordinator is } } - /** - * @notice Registers msg.sender as an operator for one or more quorums. If any quorum reaches its maximum operator - * capacity, `operatorKickParams` is used to replace an old operator with the new one. - * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for - * @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership - * @param operatorKickParams used to determine which operator is removed to maintain quorum capacity as the - * operator registers for quorums - * @param churnApproverSignature is the signature of the churnApprover over the `operatorKickParams` - * @param operatorSignature is the signature of the operator used by the AVS to register the operator in the delegation manager - * @dev `params` is ignored if the caller has previously registered a public key - * @dev `operatorSignature` is ignored if the operator's status is already REGISTERED - */ + /// @inheritdoc IRegistryCoordinator function registerOperatorWithChurn( bytes calldata quorumNumbers, string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, OperatorKickParam[] memory operatorKickParams, SignatureWithSaltAndExpiry memory churnApproverSignature, SignatureWithSaltAndExpiry memory operatorSignature @@ -266,10 +235,7 @@ contract RegistryCoordinator is } } - /** - * @notice Deregisters the caller from one or more quorums - * @param quorumNumbers is an ordered byte array containing the quorum numbers being deregistered from - */ + /// @inheritdoc IRegistryCoordinator function deregisterOperator( bytes memory quorumNumbers ) external onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) { @@ -283,10 +249,12 @@ contract RegistryCoordinator is _deregisterOperator({operator: msg.sender, quorumNumbers: quorumNumbers}); } + /// @inheritdoc IRegistryCoordinator function isUsingOperatorSets() public view returns (bool) { return isOperatorSetAVS; } + /// @inheritdoc IRegistryCoordinator function enableOperatorSets() external onlyOwner { require(!isOperatorSetAVS, OperatorSetsEnabled()); @@ -299,11 +267,16 @@ contract RegistryCoordinator is isOperatorSetAVS = true; } + /// @inheritdoc IRegistryCoordinator function registerOperator( address operator, uint32[] memory operatorSetIds, bytes memory data - ) external override onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) { + ) + external + override(IRegistryCoordinator, AVSRegistrar) + onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) + { require(isUsingOperatorSets(), OperatorSetsNotEnabled()); for (uint256 i = 0; i < operatorSetIds.length; i++) { require(!isM2Quorum[uint8(operatorSetIds[i])], OperatorSetsNotSupported()); @@ -311,8 +284,8 @@ contract RegistryCoordinator is _checkAllocationManager(); // Decode registration data from bytes - (string memory socket, IBLSApkRegistry.PubkeyRegistrationParams memory params) = - abi.decode(data, (string, IBLSApkRegistry.PubkeyRegistrationParams)); + (string memory socket, IBLSApkRegistryTypes.PubkeyRegistrationParams memory params) = + abi.decode(data, (string, IBLSApkRegistryTypes.PubkeyRegistrationParams)); // Get operator ID from BLS registry bytes32 operatorId = _getOrCreateOperatorId(operator, params); @@ -330,10 +303,15 @@ contract RegistryCoordinator is }); } + /// @inheritdoc IRegistryCoordinator function deregisterOperator( address operator, uint32[] memory operatorSetIds - ) external override onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) { + ) + external + override(IRegistryCoordinator, AVSRegistrar) + onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) + { require(isUsingOperatorSets(), OperatorSetsNotEnabled()); for (uint256 i = 0; i < operatorSetIds.length; i++) { require(!isM2Quorum[uint8(operatorSetIds[i])], OperatorSetsNotSupported()); @@ -347,12 +325,7 @@ contract RegistryCoordinator is _deregisterOperator(operator, quorumNumbers); } - /** - * @notice Updates the StakeRegistry's view of one or more operators' stakes. If any operator - * is found to be below the minimum stake for the quorum, they are deregistered. - * @dev stakes are queried from the Eigenlayer core DelegationManager contract - * @param operators a list of operator addresses to update - */ + /// @inheritdoc IRegistryCoordinator function updateOperators( address[] memory operators ) external onlyWhenNotPaused(PAUSED_UPDATE_OPERATOR) { @@ -368,20 +341,7 @@ contract RegistryCoordinator is } } - /** - * @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 - */ + /// @inheritdoc IRegistryCoordinator function updateOperatorsForQuorum( address[][] memory operatorsPerQuorum, bytes calldata quorumNumbers @@ -436,13 +396,10 @@ contract RegistryCoordinator is } } - /** - * @notice Updates the socket of the msg.sender given they are a registered operator - * @param socket is the new socket of the operator - */ + /// @inheritdoc IRegistryCoordinator function updateSocket( string memory socket - ) external { + ) external override(IRegistryCoordinator) { require(_operatorInfo[msg.sender].status == OperatorStatus.REGISTERED, NotRegistered()); emit OperatorSocketUpdate(_operatorInfo[msg.sender].operatorId, socket); } @@ -453,12 +410,7 @@ contract RegistryCoordinator is * */ - /** - * @notice Forcibly deregisters an operator from one or more quorums - * @param operator the operator to eject - * @param quorumNumbers the quorum numbers to eject the operator from - * @dev possible race condition if prior to being ejected for a set of quorums the operator self deregisters from a subset - */ + /// @inheritdoc IRegistryCoordinator function ejectOperator(address operator, bytes memory quorumNumbers) external onlyEjector { lastEjectionTimestamp[operator] = block.timestamp; @@ -481,29 +433,26 @@ contract RegistryCoordinator is * */ - /** - * @notice Creates a quorum and initializes it in each registry contract - * @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 - * For migrated AVS that enable operator sets this will create a quorum that measures total delegated stake for operator set - * - */ + /// @inheritdoc IRegistryCoordinator function createTotalDelegatedStakeQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) external virtual onlyOwner { - _createQuorum(operatorSetParams, minimumStake, strategyParams, StakeType.TOTAL_DELEGATED, 0); + _createQuorum( + operatorSetParams, + minimumStake, + strategyParams, + IStakeRegistryTypes.StakeType.TOTAL_DELEGATED, + 0 + ); } + /// @inheritdoc IRegistryCoordinator function createSlashableStakeQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams, + IStakeRegistryTypes.StrategyParams[] memory strategyParams, uint32 lookAheadPeriod ) external virtual onlyOwner { require(isUsingOperatorSets(), OperatorSetsNotEnabled()); @@ -511,18 +460,12 @@ contract RegistryCoordinator is operatorSetParams, minimumStake, strategyParams, - StakeType.TOTAL_SLASHABLE, + IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE, lookAheadPeriod ); } - /** - * @notice Updates an existing quorum's configuration with a new max operator count - * and operator churn parameters - * @param quorumNumber the quorum number to update - * @param operatorSetParams the new config - * @dev only callable by the owner - */ + /// @inheritdoc IRegistryCoordinator function setOperatorSetParams( uint8 quorumNumber, OperatorSetParam memory operatorSetParams @@ -530,35 +473,21 @@ contract RegistryCoordinator is _setOperatorSetParams(quorumNumber, operatorSetParams); } - /** - * @notice Sets the churnApprover, which approves operator registration with churn - * (see `registerOperatorWithChurn`) - * @param _churnApprover the new churn approver - * @dev only callable by the owner - */ + /// @inheritdoc IRegistryCoordinator function setChurnApprover( address _churnApprover ) external onlyOwner { _setChurnApprover(_churnApprover); } - /** - * @notice Sets the ejector, which can force-deregister operators from quorums - * @param _ejector the new ejector - * @dev only callable by the owner - */ + /// @inheritdoc IRegistryCoordinator function setEjector( address _ejector ) external onlyOwner { _setEjector(_ejector); } - /** - * @notice Sets the ejection cooldown, which is the time an operator must wait in - * seconds afer ejection before registering for any quorum - * @param _ejectionCooldown the new ejection cooldown in seconds - * @dev only callable by the owner - */ + /// @inheritdoc IRegistryCoordinator function setEjectionCooldown( uint256 _ejectionCooldown ) external onlyOwner { @@ -695,6 +624,10 @@ contract RegistryCoordinator is require(msg.sender == ejector, OnlyEjector()); } + /** + * @notice Checks if the caller is the allocation manager + * @dev Reverts if the caller is not the allocation manager + */ function _checkAllocationManager() internal view { require(msg.sender == address(allocationManager), OnlyAllocationManager()); } @@ -720,7 +653,7 @@ contract RegistryCoordinator is */ function _getOrCreateOperatorId( address operator, - IBLSApkRegistry.PubkeyRegistrationParams memory params + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params ) internal returns (bytes32 operatorId) { operatorId = blsApkRegistry.getOperatorId(operator); if (operatorId == 0) { @@ -903,8 +836,8 @@ contract RegistryCoordinator is function _createQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams, - StakeType stakeType, + IStakeRegistryTypes.StrategyParams[] memory strategyParams, + IStakeRegistryTypes.StakeType stakeType, uint32 lookAheadPeriod ) internal { // Increment the total quorum count. Fails if we're already at the max @@ -941,9 +874,9 @@ contract RegistryCoordinator is }); } // Initialize stake registry based on stake type - if (stakeType == StakeType.TOTAL_DELEGATED) { + if (stakeType == IStakeRegistryTypes.StakeType.TOTAL_DELEGATED) { stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); - } else if (stakeType == StakeType.TOTAL_SLASHABLE) { + } else if (stakeType == IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE) { stakeRegistry.initializeSlashableStakeQuorum( quorumNumber, minimumStake, lookAheadPeriod, strategyParams ); @@ -1011,46 +944,42 @@ contract RegistryCoordinator is * */ - /// @notice Returns the operator set params for the given `quorumNumber` + /// @inheritdoc IRegistryCoordinator function getOperatorSetParams( uint8 quorumNumber ) external view returns (OperatorSetParam memory) { return _quorumParams[quorumNumber]; } - /// @notice Returns the operator struct for the given `operator` + /// @inheritdoc IRegistryCoordinator function getOperator( address operator ) external view returns (OperatorInfo memory) { return _operatorInfo[operator]; } - /// @notice Returns the operatorId for the given `operator` + /// @inheritdoc IRegistryCoordinator function getOperatorId( address operator ) external view returns (bytes32) { return _operatorInfo[operator].operatorId; } - /// @notice Returns the operator address for the given `operatorId` + /// @inheritdoc IRegistryCoordinator function getOperatorFromId( bytes32 operatorId ) external view returns (address) { return blsApkRegistry.getOperatorFromPubkeyHash(operatorId); } - /// @notice Returns the status for the given `operator` + /// @inheritdoc IRegistryCoordinator function getOperatorStatus( address operator ) external view returns (IRegistryCoordinator.OperatorStatus) { return _operatorInfo[operator].status; } - /** - * @notice Returns the indices of the quorumBitmaps for the provided `operatorIds` at the given `blockNumber` - * @dev Reverts if any of the `operatorIds` was not (yet) registered at `blockNumber` - * @dev This function is designed to find proper inputs to the `getQuorumBitmapAtBlockNumberByIndex` function - */ + /// @inheritdoc IRegistryCoordinator function getQuorumBitmapIndicesAtBlockNumber( uint32 blockNumber, bytes32[] memory operatorIds @@ -1060,12 +989,7 @@ contract RegistryCoordinator is ); } - /** - * @notice Returns the quorum bitmap for the given `operatorId` at the given `blockNumber` via the `index`, - * reverting if `index` is incorrect - * @dev This function is meant to be used in concert with `getQuorumBitmapIndicesAtBlockNumber`, which - * helps off-chain processes to fetch the correct `index` input - */ + /// @inheritdoc IRegistryCoordinator function getQuorumBitmapAtBlockNumberByIndex( bytes32 operatorId, uint32 blockNumber, @@ -1076,7 +1000,7 @@ contract RegistryCoordinator is ); } - /// @notice Returns the `index`th entry in the operator with `operatorId`'s bitmap history + /// @inheritdoc IRegistryCoordinator function getQuorumBitmapUpdateByIndex( bytes32 operatorId, uint256 index @@ -1084,32 +1008,26 @@ contract RegistryCoordinator is return _operatorBitmapHistory[operatorId][index]; } - /// @notice Returns the current quorum bitmap for the given `operatorId` or 0 if the operator is not registered for any quorum + /// @inheritdoc IRegistryCoordinator function getCurrentQuorumBitmap( bytes32 operatorId ) external view returns (uint192) { return _currentOperatorBitmap(operatorId); } - /// @notice Returns the length of the quorum bitmap history for the given `operatorId` + /// @inheritdoc IRegistryCoordinator function getQuorumBitmapHistoryLength( bytes32 operatorId ) external view returns (uint256) { return _operatorBitmapHistory[operatorId].length; } - /// @notice Returns the number of registries + /// @inheritdoc IRegistryCoordinator function numRegistries() external view returns (uint256) { return registries.length; } - /** - * @notice Public function for the the churnApprover signature hash calculation when operators are being kicked from quorums - * @param registeringOperatorId The id of the registering operator - * @param operatorKickParams The parameters needed to kick the operator from the quorums that have reached their caps - * @param salt The salt to use for the churnApprover's signature - * @param expiry The desired expiry time of the churnApprover's signature - */ + /// @inheritdoc IRegistryCoordinator function calculateOperatorChurnApprovalDigestHash( address registeringOperator, bytes32 registeringOperatorId, @@ -1132,10 +1050,7 @@ contract RegistryCoordinator is ); } - /** - * @notice Returns the message hash that an operator must sign to register their BLS public key. - * @param operator is the address of the operator registering their BLS public key - */ + /// @inheritdoc IRegistryCoordinator function pubkeyRegistrationMessageHash( address operator ) public view returns (BN254.G1Point memory) { diff --git a/src/StakeRegistry.sol b/src/StakeRegistry.sol index d93763c3..e7898a59 100644 --- a/src/StakeRegistry.sol +++ b/src/StakeRegistry.sol @@ -12,7 +12,7 @@ import {IServiceManager} from "./interfaces/IServiceManager.sol"; import {StakeRegistryStorage, IStrategy} from "./StakeRegistryStorage.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; -import {IStakeRegistry, StakeType} from "./interfaces/IStakeRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./interfaces/IStakeRegistry.sol"; import {BitmapUtils} from "./libraries/BitmapUtils.sol"; @@ -67,19 +67,7 @@ contract StakeRegistry is StakeRegistryStorage { * */ - /** - * @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 The operator's current stake for each quorum, and 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 - */ + /// @inheritdoc IStakeRegistry function registerOperator( address operator, bytes32 operatorId, @@ -112,18 +100,7 @@ contract StakeRegistry is StakeRegistryStorage { return (currentStakes, 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 - */ + /// @inheritdoc IStakeRegistry function deregisterOperator( bytes32 operatorId, bytes calldata quorumNumbers @@ -148,15 +125,7 @@ contract StakeRegistry is StakeRegistryStorage { } } - /** - * @notice Called by the registry coordinator to update an operator's stake for one - * or more quorums. - * - * If the operator no longer has the minimum stake required for a quorum, they are - * added to the `quorumsToRemove`, which is returned to the registry coordinator - * @return A bitmap of quorums where the operator no longer meets the minimum stake - * and should be deregistered. - */ + /// @inheritdoc IStakeRegistry function updateOperatorStake( address operator, bytes32 operatorId, @@ -202,7 +171,7 @@ contract StakeRegistry is StakeRegistryStorage { return quorumsToRemove; } - /// @notice Initialize a new quorum and push its first history update + /// @inheritdoc IStakeRegistry function initializeDelegatedStakeQuorum( uint8 quorumNumber, uint96 minimumStake, @@ -211,7 +180,7 @@ contract StakeRegistry is StakeRegistryStorage { require(!_quorumExists(quorumNumber), QuorumAlreadyExists()); _addStrategyParams(quorumNumber, _strategyParams); _setMinimumStakeForQuorum(quorumNumber, minimumStake); - _setStakeType(quorumNumber, StakeType.TOTAL_DELEGATED); + _setStakeType(quorumNumber, IStakeRegistryTypes.StakeType.TOTAL_DELEGATED); _totalStakeHistory[quorumNumber].push( StakeUpdate({ @@ -222,7 +191,7 @@ contract StakeRegistry is StakeRegistryStorage { ); } - /// @notice Initialize a new quorum and push its first history update + /// @inheritdoc IStakeRegistry function initializeSlashableStakeQuorum( uint8 quorumNumber, uint96 minimumStake, @@ -232,7 +201,7 @@ contract StakeRegistry is StakeRegistryStorage { require(!_quorumExists(quorumNumber), QuorumAlreadyExists()); _addStrategyParams(quorumNumber, _strategyParams); _setMinimumStakeForQuorum(quorumNumber, minimumStake); - _setStakeType(quorumNumber, StakeType.TOTAL_SLASHABLE); + _setStakeType(quorumNumber, IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE); _setLookAheadPeriod(quorumNumber, lookAheadPeriod); _totalStakeHistory[quorumNumber].push( @@ -244,6 +213,7 @@ contract StakeRegistry is StakeRegistryStorage { ); } + /// @inheritdoc IStakeRegistry function setMinimumStakeForQuorum( uint8 quorumNumber, uint96 minimumStake @@ -251,11 +221,7 @@ contract StakeRegistry is StakeRegistryStorage { _setMinimumStakeForQuorum(quorumNumber, minimumStake); } - /** - * @notice Sets the look ahead time 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 - */ + /// @inheritdoc IStakeRegistry function setSlashableStakeLookahead( uint8 quorumNumber, uint32 _lookAheadBlocks @@ -263,12 +229,7 @@ contract StakeRegistry is StakeRegistryStorage { _setLookAheadPeriod(quorumNumber, _lookAheadBlocks); } - /** - * @notice Adds strategies and weights to the 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". - */ + /// @inheritdoc IStakeRegistry function addStrategies( uint8 quorumNumber, StrategyParams[] memory _strategyParams @@ -290,11 +251,7 @@ contract StakeRegistry is StakeRegistryStorage { } } - /** - * @notice Remove strategies and their associated weights from the quorum's considered strategies - * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise - * the removal of lower index entries will cause a shift in the indices of the other strategies to remove - */ + /// @inheritdoc IStakeRegistry function removeStrategies( uint8 quorumNumber, uint256[] memory indicesToRemove @@ -332,12 +289,7 @@ contract StakeRegistry is StakeRegistryStorage { } } - /** - * @notice Modifies the weights of existing strategies for a specific quorum - * @param quorumNumber is the quorum number to which the strategies belong - * @param strategyIndices are the indices of the strategies to change - * @param newMultipliers are the new multipliers for the strategies - */ + /// @inheritdoc IStakeRegistry function modifyStrategyParams( uint8 quorumNumber, uint256[] calldata strategyIndices, @@ -586,7 +538,7 @@ contract StakeRegistry is StakeRegistryStorage { StrategyParams memory strategyAndMultiplier; uint256[] memory strategyShares; - if (stakeTypePerQuorum[quorumNumber] == StakeType.TOTAL_SLASHABLE) { + if (stakeTypePerQuorum[quorumNumber] == IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE) { strategyShares = _getSlashableStakePerStrategy(quorumNumber, operator); for (uint256 i = 0; i < stratsLength; i++) { strategyAndMultiplier = strategyParams[quorumNumber][i]; @@ -631,13 +583,7 @@ contract StakeRegistry is StakeRegistryStorage { * */ - /** - * @notice Returns whether a quorum is an operator set quorum based on its stake type - * @dev A quorum is an operator set quorum if it has TOTAL_SLASHABLE stake type - * and is not an M2 quorum - * @param quorumNumber The quorum number to check - * @return True if the quorum is an operator set quorum - */ + /// @inheritdoc IStakeRegistry function isOperatorSetQuorum( uint8 quorumNumber ) public view returns (bool) { @@ -646,10 +592,7 @@ contract StakeRegistry is StakeRegistryStorage { return isOperatorSet && !isM2; } - /** - * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. - * @dev reverts if the quorum does not exist - */ + /// @inheritdoc IStakeRegistry function weightOfOperatorForQuorum( uint8 quorumNumber, address operator @@ -658,14 +601,14 @@ contract StakeRegistry is StakeRegistryStorage { return stake; } - /// @notice Returns the length of the dynamic array stored in `strategyParams[quorumNumber]`. + /// @inheritdoc IStakeRegistry function strategyParamsLength( uint8 quorumNumber ) public view returns (uint256) { return strategyParams[quorumNumber].length; } - /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` + /// @inheritdoc IStakeRegistry function strategyParamsByIndex( uint8 quorumNumber, uint256 index @@ -679,9 +622,7 @@ contract StakeRegistry is StakeRegistryStorage { * */ - /** - * @notice Returns the length of an operator's stake history for the given quorum - */ + /// @inheritdoc IStakeRegistry function getStakeHistoryLength( bytes32 operatorId, uint8 quorumNumber @@ -689,11 +630,7 @@ contract StakeRegistry is StakeRegistryStorage { return operatorStakeHistory[operatorId][quorumNumber].length; } - /** - * @notice Returns the entire `operatorStakeHistory[operatorId][quorumNumber]` array. - * @param operatorId The id of the operator of interest. - * @param quorumNumber The quorum number to get the stake for. - */ + /// @inheritdoc IStakeRegistry function getStakeHistory( bytes32 operatorId, uint8 quorumNumber @@ -701,10 +638,7 @@ contract StakeRegistry is StakeRegistryStorage { return operatorStakeHistory[operatorId][quorumNumber]; } - /** - * @notice Returns the most recent stake weight for the `operatorId` for quorum `quorumNumber` - * @dev Function returns weight of **0** in the event that the operator has no stake history - */ + /// @inheritdoc IStakeRegistry function getCurrentStake( bytes32 operatorId, uint8 quorumNumber @@ -713,10 +647,7 @@ contract StakeRegistry is StakeRegistryStorage { return operatorStakeUpdate.stake; } - /** - * @notice Returns the most recent stake weight for the `operatorId` for a certain quorum - * @dev Function returns an StakeUpdate struct with **every entry equal to 0** in the event that the operator has no stake history - */ + /// @inheritdoc IStakeRegistry function getLatestStakeUpdate( bytes32 operatorId, uint8 quorumNumber @@ -731,13 +662,7 @@ contract StakeRegistry is StakeRegistryStorage { } } - /** - * @notice Returns the `index`-th entry in the `operatorStakeHistory[operatorId][quorumNumber]` array. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorStakeHistory[operatorId][quorumNumber]`. - * @dev Function will revert if `index` is out-of-bounds. - */ + /// @inheritdoc IStakeRegistry function getStakeUpdateAtIndex( uint8 quorumNumber, bytes32 operatorId, @@ -746,7 +671,7 @@ contract StakeRegistry is StakeRegistryStorage { return operatorStakeHistory[operatorId][quorumNumber][index]; } - /// @notice Returns the stake of the operator for the provided `quorumNumber` at the given `blockNumber` + /// @inheritdoc IStakeRegistry function getStakeAtBlockNumber( bytes32 operatorId, uint8 quorumNumber, @@ -757,7 +682,7 @@ contract StakeRegistry is StakeRegistryStorage { )].stake; } - /// @notice Returns the indices of the operator stakes for the provided `quorumNumber` at the given `blockNumber` + /// @inheritdoc IStakeRegistry function getStakeUpdateIndexAtBlockNumber( bytes32 operatorId, uint8 quorumNumber, @@ -766,16 +691,7 @@ contract StakeRegistry is StakeRegistryStorage { return _getStakeUpdateIndexForOperatorAtBlockNumber(operatorId, quorumNumber, blockNumber); } - /** - * @notice Returns the stake weight corresponding to `operatorId` for quorum `quorumNumber`, at the - * `index`-th entry in the `operatorStakeHistory[operatorId][quorumNumber]` array if it was the operator's - * stake at `blockNumber`. Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorStakeHistory[operatorId][quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - */ + /// @inheritdoc IStakeRegistry function getStakeAtBlockNumberAndIndex( uint8 quorumNumber, uint32 blockNumber, @@ -794,30 +710,21 @@ contract StakeRegistry is StakeRegistryStorage { * */ - /** - * @notice Returns the length of the total stake history for the given quorum - */ + /// @inheritdoc IStakeRegistry function getTotalStakeHistoryLength( uint8 quorumNumber ) external view returns (uint256) { return _totalStakeHistory[quorumNumber].length; } - /** - * @notice Returns the stake weight from the latest entry in `_totalStakeHistory` for quorum `quorumNumber`. - * @dev Will revert if `_totalStakeHistory[quorumNumber]` is empty. - */ + /// @inheritdoc IStakeRegistry function getCurrentTotalStake( uint8 quorumNumber ) external view returns (uint96) { return _totalStakeHistory[quorumNumber][_totalStakeHistory[quorumNumber].length - 1].stake; } - /** - * @notice Returns the `index`-th entry in the dynamic array of total stake, `_totalStakeHistory` for quorum `quorumNumber`. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `_totalStakeHistory[quorumNumber]`. - */ + /// @inheritdoc IStakeRegistry function getTotalStakeUpdateAtIndex( uint8 quorumNumber, uint256 index @@ -825,14 +732,7 @@ contract StakeRegistry is StakeRegistryStorage { return _totalStakeHistory[quorumNumber][index]; } - /** - * @notice Returns the total stake weight for quorum `quorumNumber`, at the `index`-th entry in the - * `_totalStakeHistory[quorumNumber]` array if it was the stake at `blockNumber`. Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `_totalStakeHistory[quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - */ + /// @inheritdoc IStakeRegistry function getTotalStakeAtBlockNumberFromIndex( uint8 quorumNumber, uint32 blockNumber, @@ -843,12 +743,7 @@ contract StakeRegistry is StakeRegistryStorage { return totalStakeUpdate.stake; } - /** - * @notice Returns the indices of the total stakes for the provided `quorumNumbers` at the given `blockNumber` - * @param blockNumber Block number to retrieve the stake indices from. - * @param quorumNumbers The quorum numbers to get the stake indices for. - * @dev Function will revert if there are no indices for the given `blockNumber` - */ + /// @inheritdoc IStakeRegistry function getTotalStakeIndicesAtBlockNumber( uint32 blockNumber, bytes calldata quorumNumbers @@ -880,7 +775,7 @@ contract StakeRegistry is StakeRegistryStorage { * @param quorumNumber The quorum number to set the stake type for * @param _stakeType The type of stake to track (TOTAL_DELEGATED, TOTAL_SLASHABLE, or BOTH) */ - function _setStakeType(uint8 quorumNumber, StakeType _stakeType) internal { + function _setStakeType(uint8 quorumNumber, IStakeRegistryTypes.StakeType _stakeType) internal { stakeTypePerQuorum[quorumNumber] = _stakeType; emit StakeTypeSet(_stakeType); } diff --git a/src/StakeRegistryStorage.sol b/src/StakeRegistryStorage.sol index c0d7b933..67557c6d 100644 --- a/src/StakeRegistryStorage.sol +++ b/src/StakeRegistryStorage.sol @@ -13,7 +13,7 @@ import { } from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; -import {IStakeRegistry, StakeType} from "./interfaces/IStakeRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./interfaces/IStakeRegistry.sol"; /** * @title Storage variables for the `StakeRegistry` contract. @@ -62,8 +62,8 @@ abstract contract StakeRegistryStorage is IStakeRegistry { /// @notice mapping from quorum number to the list of strategies considered for that specific quorum mapping(uint8 quorumNumber => IStrategy[]) public strategiesPerQuorum; - /// @notice mapping from quorum number to the StakeType for that specific quorum - mapping(uint8 quorumNumber => StakeType) public stakeTypePerQuorum; + /// @notice mapping from quorum number to the IStakeRegistryTypes.StakeType for that specific quorum + mapping(uint8 quorumNumber => IStakeRegistryTypes.StakeType) public stakeTypePerQuorum; /// @notice mapping from quorum number to the slashable stake look ahead time (in blocks) mapping(uint8 quorumNumber => uint32) public slashableStakeLookAheadPerQuorum; diff --git a/src/interfaces/IBLSApkRegistry.sol b/src/interfaces/IBLSApkRegistry.sol index 0b1370b5..1a410009 100644 --- a/src/interfaces/IBLSApkRegistry.sol +++ b/src/interfaces/IBLSApkRegistry.sol @@ -1,183 +1,236 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IRegistry} from "./IRegistry.sol"; - import {BN254} from "../libraries/BN254.sol"; interface IBLSApkRegistryErrors { - /// @dev Thrown when the caller is not the owner of the registry coordinator. + /// @notice Thrown when a non-RegistryCoordinator address calls a restricted function. error OnlyRegistryCoordinatorOwner(); - /// @dev Thrown when a quorum being created already exists. + /// @notice Thrown when attempting to initialize a quorum that already exists. error QuorumAlreadyExists(); - /// @dev Thrown when a quorum does not exist. + /// @notice Thrown when a quorum does not exist. error QuorumDoesNotExist(); - /// @dev Thrown when a BLS pubkey provided is zero pubkey + /// @notice Thrown when a BLS pubkey provided is zero pubkey error ZeroPubKey(); - /// @dev Thrown when an operator has already registered a BLS pubkey. + /// @notice Thrown when an operator has already registered a BLS pubkey. error OperatorAlreadyRegistered(); - /// @dev Thrown when the operator is not registered. + /// @notice Thrown when the operator is not registered. error OperatorNotRegistered(); - /// @dev Thrown when a BLS pubkey has already been registered for an operator. + /// @notice Thrown when a BLS pubkey has already been registered for an operator. error BLSPubkeyAlreadyRegistered(); - /// @dev Thrown when either the G1 signature is wrong, or G1 and G2 private key do not match. + /// @notice Thrown when either the G1 signature is wrong, or G1 and G2 private key do not match. error InvalidBLSSignatureOrPrivateKey(); - /// @dev Thrown when the quorum apk update block number is too recent. + /// @notice Thrown when the quorum apk update block number is too recent. error BlockNumberTooRecent(); - /// @dev Thrown when blocknumber and index provided is not the latest apk update. + /// @notice Thrown when blocknumber and index provided is not the latest apk update. error BlockNumberNotLatest(); } -/** - * @title Minimal interface for a registry that keeps track of aggregate operator public keys across many quorums. - * @author Layr Labs, Inc. - */ -interface IBLSApkRegistry is IRegistry, IBLSApkRegistryErrors { - // STRUCTS - /// @notice Data structure used to track the history of the Aggregate Public Key of all operators +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 { - // first 24 bytes of keccak256(apk_x0, apk_x1, apk_y0, apk_y1) bytes24 apkHash; - // block number at which the update occurred uint32 updateBlockNumber; - // block number at which the next update occurred uint32 nextUpdateBlockNumber; } - /** - * @notice Struct used when registering a new public key - * @param pubkeyRegistrationSignature is the registration message signed by the private key of the operator - * @param pubkeyG1 is the corresponding G1 public key of the operator - * @param pubkeyG2 is the corresponding G2 public key of the operator - */ + /// @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; } +} - // EVENTS - /// @notice Emitted when `operator` registers with the public keys `pubkeyG1` and `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 a new operator pubkey is registered for a set of quorums + /// @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 an operator pubkey is removed from a set of quorums + /// @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); +} + +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 Registers the `operator`'s pubkey for the specified `quorumNumbers`. - * @param operator The address of the operator to register. - * @param quorumNumbers The quorum numbers the operator is registering for, 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 registered - */ + /// @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 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 the `operator`'s pubkey for the specified `quorumNumbers`. - * @param operator The address 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 - */ + /// @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 a new quorum by pushing its first apk update - * @param quorumNumber The number of the new quorum - */ + /// @notice Initializes `quorumNumber` by pushing its first APK update. + /// @param quorumNumber The number of the new quorum. function initializeQuorum( uint8 quorumNumber ) external; - /** - * @notice mapping from operator address to pubkey hash. - * Returns *zero* if the `operator` has never registered, and otherwise returns the hash of the public key of the operator. - */ - function operatorToPubkeyHash( - address operator - ) external view returns (bytes32); - - /** - * @notice mapping from pubkey hash to operator address. - * Returns *zero* if no operator has ever registered the public key corresponding to `pubkeyHash`, - * and otherwise returns the (unique) registered operator who owns the BLS public key that is the preimage of `pubkeyHash`. - */ - function pubkeyHashToOperator( - bytes32 pubkeyHash - ) external view returns (address); - - /** - * @notice Called by the RegistryCoordinator register an operator as the owner of a BLS public key. - * @param operator is the operator for whom the key is being registered - * @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership - * @param pubkeyRegistrationMessageHash is a hash that the operator must sign to prove key ownership - */ + /// @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, - PubkeyRegistrationParams calldata params, + IBLSApkRegistryTypes.PubkeyRegistrationParams calldata params, BN254.G1Point calldata pubkeyRegistrationMessageHash ) external returns (bytes32 operatorId); - /** - * @notice Returns the pubkey and pubkey hash of an operator - * @dev Reverts if the operator has not registered a valid pubkey - */ + /// 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 current APK for the provided `quorumNumber ` - function getApk( - uint8 quorumNumber - ) external view returns (BN254.G1Point memory); - - /// @notice Returns the index of the quorumApk index at `blockNumber` for the provided `quorumNumber` + /// @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 `ApkUpdate` struct at `index` in the list of APK updates for the `quorumNumber` + /// @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 (ApkUpdate memory); - - /// @notice Returns the operator address for the given `pubkeyHash` - function getOperatorFromPubkeyHash( - bytes32 pubkeyHash - ) external view returns (address); - - /** - * @notice get 24 byte hash of the apk of `quorumNumber` at `blockNumber` using the provided `index`; - * called by checkSignatures in BLSSignatureChecker.sol. - * @param quorumNumber is the quorum whose ApkHash is being retrieved - * @param blockNumber is the number of the block for which the latest ApkHash will be retrieved - * @param index is the index of the apkUpdate being retrieved from the list of quorum apkUpdates in storage - */ + ) 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 ID used to identify the `operator` within this AVS. - /// @dev Returns zero in the event that the `operator` has never registered for the AVS + /// @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); + ) 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); } diff --git a/src/interfaces/IBLSSignatureChecker.sol b/src/interfaces/IBLSSignatureChecker.sol index 6a7df2c5..c19bd8d2 100644 --- a/src/interfaces/IBLSSignatureChecker.sol +++ b/src/interfaces/IBLSSignatureChecker.sol @@ -8,91 +8,143 @@ import {IStakeRegistry, IDelegationManager} from "./IStakeRegistry.sol"; import {BN254} from "../libraries/BN254.sol"; interface IBLSSignatureCheckerErrors { - /// @dev Thrown when the caller is not the registry coordinator owner. + /// @notice Thrown when the caller is not the registry coordinator owner. error OnlyRegistryCoordinatorOwner(); - /// @dev Thrown when the quorum numbers input in is empty. + /// @notice Thrown when the quorum numbers input in is empty. error InputEmptyQuorumNumbers(); - /// @dev Thrown when two array parameters have mismatching lengths. + /// @notice Thrown when two array parameters have mismatching lengths. error InputArrayLengthMismatch(); - /// @dev Thrown when the non-signer pubkey length does not match non-signer bitmap indices length. + /// @notice Thrown when the non-signer pubkey length does not match non-signer bitmap indices length. error InputNonSignerLengthMismatch(); - /// @dev Thrown when the reference block number is invalid. + /// @notice Thrown when the reference block number is invalid. error InvalidReferenceBlocknumber(); - /// @dev Thrown when the non signer pubkeys are not sorted. + /// @notice Thrown when the non signer pubkeys are not sorted. error NonSignerPubkeysNotSorted(); - /// @dev Thrown when StakeRegistry updates have not been updated within withdrawalDelayBlocks window + /// @notice Thrown when StakeRegistry updates have not been updated within withdrawalDelayBlocks window error StaleStakesForbidden(); - /// @dev Thrown when the quorum apk hash in storage does not match provided quorum apk. + /// @notice Thrown when the quorum apk hash in storage does not match provided quorum apk. error InvalidQuorumApkHash(); - /// @dev Thrown when BLS pairing precompile call fails. + /// @notice Thrown when BLS pairing precompile call fails. error InvalidBLSPairingKey(); - /// @dev Thrown when BLS signature is invalid. + /// @notice Thrown when BLS signature is invalid. error InvalidBLSSignature(); } -/** - * @title Used for checking BLS aggregate signatures from the operators of a EigenLayer AVS with the RegistryCoordinator/BLSApkRegistry/StakeRegistry architechture. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice This is the contract for checking the validity of aggregate operator signatures. - */ -interface IBLSSignatureChecker is IBLSSignatureCheckerErrors { - // DATA STRUCTURES +interface IBLSSignatureCheckerTypes { + /// @notice Contains bitmap and pubkey hash information for non-signing operators. + /// @param quorumBitmaps Array of bitmaps indicating which quorums each non-signer was registered for. + /// @param pubkeyHashes Array of BLS public key hashes for each non-signer. + struct NonSignerInfo { + uint256[] quorumBitmaps; + bytes32[] pubkeyHashes; + } + /// @notice Contains non-signer information and aggregated signature data for BLS verification. + /// @param nonSignerQuorumBitmapIndices The indices of all non-signer quorum bitmaps. + /// @param nonSignerPubkeys The G1 public keys of all non-signers. + /// @param quorumApks The aggregate G1 public key of each quorum. + /// @param apkG2 The aggregate G2 public key of all signers. + /// @param sigma The aggregate G1 signature of all signers. + /// @param quorumApkIndices The indices of each quorum's aggregate public key in the APK registry. + /// @param totalStakeIndices The indices of each quorum's total stake in the stake registry. + /// @param nonSignerStakeIndices The indices of each non-signer's stake within each quorum. + /// @dev Used as input to checkSignatures() to verify BLS signatures. struct NonSignerStakesAndSignature { - uint32[] nonSignerQuorumBitmapIndices; // is the indices of all nonsigner quorum bitmaps - BN254.G1Point[] nonSignerPubkeys; // is the G1 pubkeys of all nonsigners - BN254.G1Point[] quorumApks; // is the aggregate G1 pubkey of each quorum - BN254.G2Point apkG2; // is the aggregate G2 pubkey of all signers - BN254.G1Point sigma; // is the aggregate G1 signature of all signers - uint32[] quorumApkIndices; // is the indices of each quorum aggregate pubkey - uint32[] totalStakeIndices; // is the indices of each quorums total stake - uint32[][] nonSignerStakeIndices; // is the indices of each non signers stake within a quorum + uint32[] nonSignerQuorumBitmapIndices; + BN254.G1Point[] nonSignerPubkeys; + BN254.G1Point[] quorumApks; + BN254.G2Point apkG2; + BN254.G1Point sigma; + uint32[] quorumApkIndices; + uint32[] totalStakeIndices; + uint32[][] nonSignerStakeIndices; } - /** - * @notice this data structure is used for recording the details on the total stake of the registered - * operators and those operators who are part of the quorum for a particular taskNumber - */ + /// @notice Records the total stake amounts for operators in each quorum. + /// @param signedStakeForQuorum Array of total stake amounts from operators who signed, per quorum. + /// @param totalStakeForQuorum Array of total stake amounts from all operators, per quorum. + /// @dev Used to track stake distribution and calculate quorum thresholds. Array indices correspond to quorum numbers. struct QuorumStakeTotals { - // total stake of the operators in each quorum uint96[] signedStakeForQuorum; - // total amount staked by all operators in each quorum uint96[] totalStakeForQuorum; } +} - // EVENTS - +interface IBLSSignatureCheckerEvents is IBLSSignatureCheckerTypes { /// @notice Emitted when `staleStakesForbiddenUpdate` is set event StaleStakesForbiddenUpdate(bool value); +} - // CONSTANTS & IMMUTABLES +interface IBLSSignatureChecker is IBLSSignatureCheckerErrors, IBLSSignatureCheckerEvents { + /// STATE + /// @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 (IRegistryCoordinator); + + /// @notice Returns the address of the stake registry contract. + /// @return The address of the stake registry. + /// @dev This value is immutable and set during contract construction. function stakeRegistry() external view returns (IStakeRegistry); + + /// @notice Returns the address of the BLS APK registry contract. + /// @return The address of the BLS APK registry. + /// @dev This value is immutable and set during contract construction. function blsApkRegistry() external view returns (IBLSApkRegistry); + + /// @notice Returns the address of the delegation manager contract. + /// @return The address of the delegation manager. + /// @dev This value is immutable and set during contract construction. function delegation() external view returns (IDelegationManager); - /** - * @notice This function is called by disperser when it has aggregated all the signatures of the operators - * that are part of the quorum for a particular taskNumber and is asserting them into onchain. The function - * checks that the claim for aggregated signatures are valid. - * - * The thesis of this procedure entails: - * - getting the aggregated pubkey of all registered nodes at the time of pre-commit by the - * disperser (represented by apk in the parameters), - * - subtracting the pubkeys of all the signers not in the quorum (nonSignerPubkeys) and storing - * the output in apk to get aggregated pubkey of all operators that are part of quorum. - * - use this aggregated pubkey to verify the aggregated signature under BLS scheme. - * - * @dev Before signature verification, the function verifies operator stake information. This includes ensuring that the provided `referenceBlockNumber` - * is correct, i.e., ensure that the stake returned from the specified block number is recent enough and that the stake is either the most recent update - * for the total stake (or the operator) or latest before the referenceBlockNumber. - */ + /// @notice Returns whether stale stakes are forbidden in signature verification. + /// @return True if stale stakes are forbidden, false otherwise. + function staleStakesForbidden() external view returns (bool); + + // ACTIONS + + /// @notice Sets `value` as the new staleStakesForbidden flag. + /// @param value True to forbid stale stakes, false to allow them. + /// @dev Access restricted to the registry coordinator owner. + function setStaleStakesForbidden( + bool value + ) external; + + /// VIEW + + /// @notice Verifies aggregated BLS signatures and stake information for message hash `msgHash` across `quorumNumbers` at block `referenceBlockNumber`. + /// @param msgHash The hash of the message that was signed. + /// @param quorumNumbers The quorum numbers to verify signatures for, where each byte is an 8-bit integer. + /// @param referenceBlockNumber The block number to use for stake information. + /// @param nonSignerStakesAndSignature Contains non-signer information and aggregated signature data. + /// @return Stake totals for each quorum and a hash of the verification data. + /// @dev The thesis of this procedure entails: + /// 1. Getting the aggregated pubkey of all registered nodes at the time of pre-commit + /// 2. Subtracting the pubkeys of all non-signers (nonSignerPubkeys) + /// 3. Using the resulting aggregated pubkey to verify the aggregated signature under BLS scheme + /// @dev Before signature verification, the function verifies: + /// 1. The reference block number is valid and recent enough + /// 2. Stake information is either most recent or latest before reference block + /// 3. The aggregated signature is valid under the BLS scheme function checkSignatures( bytes32 msgHash, bytes calldata quorumNumbers, uint32 referenceBlockNumber, NonSignerStakesAndSignature memory nonSignerStakesAndSignature ) external view returns (QuorumStakeTotals memory, bytes32); + + /// @notice Attempts to verify signature `sigma` against message hash `msgHash` using aggregate public keys `apk` and `apkG2`. + /// @param msgHash The hash of the message that was signed. + /// @param apk The aggregate public key in G1. + /// @param apkG2 The aggregate public key in G2. + /// @param sigma The signature to verify. + /// @return pairingSuccessful True if the pairing check succeeded. + /// @return siganatureIsValid True if the signature is valid. + function trySignatureAndApkVerification( + bytes32 msgHash, + BN254.G1Point memory apk, + BN254.G2Point memory apkG2, + BN254.G1Point memory sigma + ) external view returns (bool pairingSuccessful, bool siganatureIsValid); } diff --git a/src/interfaces/IECDSAStakeRegistry.sol b/src/interfaces/IECDSAStakeRegistry.sol new file mode 100644 index 00000000..acc725c3 --- /dev/null +++ b/src/interfaces/IECDSAStakeRegistry.sol @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import {IERC1271Upgradeable} from + "@openzeppelin-upgrades/contracts/interfaces/IERC1271Upgradeable.sol"; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; +import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; +import {IDelegationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; + +// TODO: many of these errors do not have test coverage. + +interface IECDSAStakeRegistryErrors { + /// @notice Thrown when the lengths of the signers array and signatures array do not match. + error LengthMismatch(); + /// @notice Thrown when encountering an invalid length for the signers or signatures array. + error InvalidLength(); + /// @notice Thrown when encountering an invalid signature. + error InvalidSignature(); + /// @notice Thrown when the threshold update is greater than BPS. + error InvalidThreshold(); + /// @notice Thrown when missing operators in an update. + error MustUpdateAllOperators(); + /// @notice Thrown when reference blocks must be for blocks that have already been confirmed. + error InvalidReferenceBlock(); + /// @notice Thrown when operator weights were out of sync and the signed weight exceed the total. + error InvalidSignedWeight(); + /// @notice Thrown when the total signed stake fails to meet the required threshold. + error InsufficientSignedStake(); + /// @notice Thrown when an individual signer's weight fails to meet the required threshold. + error InsufficientWeight(); + /// @notice Thrown when the quorum is invalid. + error InvalidQuorum(); + /// @notice Thrown when the system finds a list of items unsorted. + error NotSorted(); + /// @notice Thrown when registering an already registered operator. + error OperatorAlreadyRegistered(); + /// @notice Thrown when de-registering or updating the stake for an unregisted operator. + error OperatorNotRegistered(); +} + +interface IECDSAStakeRegistryTypes { + /// @notice Parameters for a strategy and its weight multiplier. + /// @param strategy The strategy contract reference. + /// @param multiplier The multiplier applied to the strategy. + struct StrategyParams { + IStrategy strategy; + uint96 multiplier; + } + + /// @notice Configuration for a quorum's strategies. + /// @param strategies An array of strategy parameters defining the quorum. + struct Quorum { + StrategyParams[] strategies; + } +} + +interface IECDSAStakeRegistryEvents is IECDSAStakeRegistryTypes { + /// @notice Emitted when the system registers an operator + /// @param operator The address of the registered operator + /// @param avs The address of the associated AVS + event OperatorRegistered(address indexed operator, address indexed avs); + + /// @notice Emitted when the system deregisters an operator + /// @param operator The address of the deregistered operator + /// @param avs The address of the associated AVS + event OperatorDeregistered(address indexed operator, address indexed avs); + + /// @notice Emitted when the system updates the quorum + /// @param previous The previous quorum configuration + /// @param current The new quorum configuration + event QuorumUpdated(Quorum previous, Quorum current); + + /// @notice Emitted when the weight to join the operator set updates + /// @param previous The previous minimum weight + /// @param current The new minimumWeight + event MinimumWeightUpdated(uint256 previous, uint256 current); + + /// @notice Emitted when the weight required to be an operator changes + /// @param oldMinimumWeight The previous weight + /// @param newMinimumWeight The updated weight + event UpdateMinimumWeight(uint256 oldMinimumWeight, uint256 newMinimumWeight); + + /// @notice Emitted when the system updates an operator's weight + /// @param operator The address of the operator updated + /// @param oldWeight The operator's weight before the update + /// @param newWeight The operator's weight after the update + event OperatorWeightUpdated(address indexed operator, uint256 oldWeight, uint256 newWeight); + + /// @notice Emitted when the system updates the total weight + /// @param oldTotalWeight The total weight before the update + /// @param newTotalWeight The total weight after the update + event TotalWeightUpdated(uint256 oldTotalWeight, uint256 newTotalWeight); + + /// @notice Emits when setting a new threshold weight. + event ThresholdWeightUpdated(uint256 thresholdWeight); + + /// @notice Emitted when an operator's signing key is updated + /// @param operator The address of the operator whose signing key was updated + /// @param updateBlock The block number at which the signing key was updated + /// @param newSigningKey The operator's signing key after the update + /// @param oldSigningKey The operator's signing key before the update + event SigningKeyUpdate( + address indexed operator, + uint256 indexed updateBlock, + address indexed newSigningKey, + address oldSigningKey + ); +} + +interface IECDSAStakeRegistry is + IECDSAStakeRegistryErrors, + IECDSAStakeRegistryEvents, + IERC1271Upgradeable +{ + /// ACTIONS + + /// @notice Registers a new operator using a provided operators signature and signing key. + /// @param operatorSignature Contains the operator's signature, salt, and expiry. + /// @param signingKey The signing key to add to the operator's history. + function registerOperatorWithSignature( + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature, + address signingKey + ) external; + + /// @notice Deregisters an existing operator. + function deregisterOperator() external; + + /// @notice Updates the signing key for an operator. + /// @param newSigningKey The new signing key to set for the operator. + /// @dev Only callable by the operator themselves. + function updateOperatorSigningKey( + address newSigningKey + ) external; + + /// @notice Updates the StakeRegistry's view of operators' stakes. + /// @param operators A list of operator addresses to update. + /// @dev Queries stakes from the Eigenlayer core DelegationManager contract. + function updateOperators( + address[] memory operators + ) external; + + /// @notice Updates the quorum configuration and the set of operators. + /// @param quorum The new quorum configuration, including strategies and their new weights. + /// @param operators The list of operator addresses to update stakes for. + function updateQuorumConfig( + IECDSAStakeRegistryTypes.Quorum memory quorum, + address[] memory operators + ) external; + + /// @notice Updates the weight an operator must have to join the operator set. + /// @param newMinimumWeight The new weight an operator must have to join the operator set. + /// @param operators The list of operators to update after changing the minimum weight. + function updateMinimumWeight(uint256 newMinimumWeight, address[] memory operators) external; + + /// @notice Sets a new cumulative threshold weight for message validation. + /// @param thresholdWeight The updated threshold weight required to validate a message. + function updateStakeThreshold( + uint256 thresholdWeight + ) external; + + /// VIEW + + /// @notice Retrieves the current stake quorum details. + /// @return The current quorum of strategies and weights. + function quorum() external view returns (IECDSAStakeRegistryTypes.Quorum memory); + + /// @notice Retrieves the latest signing key for a given operator. + /// @param operator The address of the operator. + /// @return The latest signing key of the operator. + function getLatestOperatorSigningKey( + address operator + ) external view returns (address); + + /// @notice Retrieves the signing key for an operator at a specific block. + /// @param operator The address of the operator. + /// @param blockNumber The block number to query at. + /// @return The signing key of the operator at the given block. + function getOperatorSigningKeyAtBlock( + address operator, + uint256 blockNumber + ) external view returns (address); + + /// @notice Retrieves the last recorded weight for a given operator. + /// @param operator The address of the operator. + /// @return The latest weight of the operator. + function getLastCheckpointOperatorWeight( + address operator + ) external view returns (uint256); + + /// @notice Retrieves the last recorded total weight across all operators. + /// @return The latest total weight. + function getLastCheckpointTotalWeight() external view returns (uint256); + + /// @notice Retrieves the last recorded threshold weight. + /// @return The latest threshold weight. + function getLastCheckpointThresholdWeight() external view returns (uint256); + + /// @notice Returns whether an operator is currently registered. + /// @param operator The operator address to check. + /// @return Whether the operator is registered. + function operatorRegistered( + address operator + ) external view returns (bool); + + /// @notice Returns the minimum weight required for operator participation. + /// @return The minimum weight threshold. + function minimumWeight() external view returns (uint256); + + /// @notice Retrieves the operator's weight at a specific block number. + /// @param operator The address of the operator. + /// @param blockNumber The block number to query at. + /// @return The weight of the operator at the given block. + function getOperatorWeightAtBlock( + address operator, + uint32 blockNumber + ) external view returns (uint256); + + /// @notice Retrieves the operator's weight. + /// @param operator The address of the operator. + /// @return The current weight of the operator. + function getOperatorWeight( + address operator + ) external view returns (uint256); + + /// @notice Updates operators for a specific quorum. + /// @param operatorsPerQuorum Array of operator addresses per quorum. + /// @param data Additional data (unused but kept for interface compatibility). + function updateOperatorsForQuorum( + address[][] memory operatorsPerQuorum, + bytes memory data + ) external; + + /// @notice Retrieves the total weight at a specific block number. + /// @param blockNumber The block number to query at. + /// @return The total weight at the given block. + function getLastCheckpointTotalWeightAtBlock( + uint32 blockNumber + ) external view returns (uint256); + + /// @notice Retrieves the threshold weight at a specific block number. + /// @param blockNumber The block number to query at. + /// @return The threshold weight at the given block. + function getLastCheckpointThresholdWeightAtBlock( + uint32 blockNumber + ) external view returns (uint256); +} diff --git a/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol b/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol deleted file mode 100644 index 96bea50a..00000000 --- a/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.27; - -import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; - -struct StrategyParams { - IStrategy strategy; // The strategy contract reference - uint96 multiplier; // The multiplier applied to the strategy -} - -struct Quorum { - StrategyParams[] strategies; // An array of strategy parameters to define the quorum -} - -interface ECDSAStakeRegistryEventsAndErrors { - /// @notice Emitted when the system registers an operator - /// @param _operator The address of the registered operator - /// @param _avs The address of the associated AVS - event OperatorRegistered(address indexed _operator, address indexed _avs); - - /// @notice Emitted when the system deregisters an operator - /// @param _operator The address of the deregistered operator - /// @param _avs The address of the associated AVS - event OperatorDeregistered(address indexed _operator, address indexed _avs); - - /// @notice Emitted when the system updates the quorum - /// @param _old The previous quorum configuration - /// @param _new The new quorum configuration - event QuorumUpdated(Quorum _old, Quorum _new); - - /// @notice Emitted when the weight to join the operator set updates - /// @param _old The previous minimum weight - /// @param _new The new minimumWeight - event MinimumWeightUpdated(uint256 _old, uint256 _new); - - /// @notice Emitted when the weight required to be an operator changes - /// @param oldMinimumWeight The previous weight - /// @param newMinimumWeight The updated weight - event UpdateMinimumWeight(uint256 oldMinimumWeight, uint256 newMinimumWeight); - - /// @notice Emitted when the system updates an operator's weight - /// @param _operator The address of the operator updated - /// @param oldWeight The operator's weight before the update - /// @param newWeight The operator's weight after the update - event OperatorWeightUpdated(address indexed _operator, uint256 oldWeight, uint256 newWeight); - - /// @notice Emitted when the system updates the total weight - /// @param oldTotalWeight The total weight before the update - /// @param newTotalWeight The total weight after the update - event TotalWeightUpdated(uint256 oldTotalWeight, uint256 newTotalWeight); - - /// @notice Emits when setting a new threshold weight. - event ThresholdWeightUpdated(uint256 _thresholdWeight); - - /// @notice Emitted when an operator's signing key is updated - /// @param operator The address of the operator whose signing key was updated - /// @param updateBlock The block number at which the signing key was updated - /// @param newSigningKey The operator's signing key after the update - /// @param oldSigningKey The operator's signing key before the update - event SigningKeyUpdate( - address indexed operator, - uint256 indexed updateBlock, - address indexed newSigningKey, - address oldSigningKey - ); - /// @notice Indicates when the lengths of the signers array and signatures array do not match. - - error LengthMismatch(); - - /// @notice Indicates encountering an invalid length for the signers or signatures array. - error InvalidLength(); - - /// @notice Indicates encountering an invalid signature. - error InvalidSignature(); - - /// @notice Thrown when the threshold update is greater than BPS - error InvalidThreshold(); - - /// @notice Thrown when missing operators in an update - error MustUpdateAllOperators(); - - /// @notice Reference blocks must be for blocks that have already been confirmed - error InvalidReferenceBlock(); - - /// @notice Indicates operator weights were out of sync and the signed weight exceed the total - error InvalidSignedWeight(); - - /// @notice Indicates the total signed stake fails to meet the required threshold. - error InsufficientSignedStake(); - - /// @notice Indicates an individual signer's weight fails to meet the required threshold. - error InsufficientWeight(); - - /// @notice Indicates the quorum is invalid - error InvalidQuorum(); - - /// @notice Indicates the system finds a list of items unsorted - error NotSorted(); - - /// @notice Thrown when registering an already registered operator - error OperatorAlreadyRegistered(); - - /// @notice Thrown when de-registering or updating the stake for an unregisted operator - error OperatorNotRegistered(); -} diff --git a/src/interfaces/IEjectionManager.sol b/src/interfaces/IEjectionManager.sol index a491a973..000740d6 100644 --- a/src/interfaces/IEjectionManager.sol +++ b/src/interfaces/IEjectionManager.sol @@ -1,70 +1,128 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.27; +import {IRegistryCoordinator} from "./IRegistryCoordinator.sol"; +import {IStakeRegistry} from "./IStakeRegistry.sol"; + interface IEjectionManagerErrors { - /// @dev Thrown when the caller is not the owner or ejector. + /// @notice Thrown when the caller is not the owner or ejector. error OnlyOwnerOrEjector(); - /// @dev Thrown when quorum number exceeds MAX_QUORUM_COUNT. + /// @notice Thrown when quorum number exceeds MAX_QUORUM_COUNT. error MaxQuorumCount(); } -/** - * @title Interface for a contract that ejects operators from an AVSs RegistryCoordinator - * @author Layr Labs, Inc. - */ -interface IEjectionManager is IEjectionManagerErrors { - /// @notice A quorum's ratelimit parameters +interface IEjectionManagerTypes { + /// @notice Parameters for controlling ejection rate limits per quorum. + /// @param rateLimitWindow Time window to track ejection rate (in seconds). + /// @param ejectableStakePercent Maximum percentage of stake that can be ejected per window (in BIPS). struct QuorumEjectionParams { - uint32 rateLimitWindow; // Time delta to track ejection over - uint16 ejectableStakePercent; // Max stake to be ejectable per time delta + uint32 rateLimitWindow; + uint16 ejectableStakePercent; } - /// @notice A stake ejection event + /// @notice Records a stake ejection event with timing and amount. + /// @param timestamp Time when the ejection occurred. + /// @param stakeEjected Amount of stake that was ejected. struct StakeEjection { - uint256 timestamp; // Timestamp of the ejection - uint256 stakeEjected; // Amount of stake ejected at the timestamp + uint256 timestamp; + uint256 stakeEjected; } +} - ///@notice Emitted when the ejector address is set +interface IEjectionManagerEvents is IEjectionManagerTypes { + /// @notice Emitted when the ejector address is set. + /// @param ejector The address being configured as ejector. + /// @param status The new status for the ejector address. event EjectorUpdated(address ejector, bool status); - ///@notice Emitted when the ratelimit parameters for a quorum are set + + /// @notice Emitted when the rate limit parameters for a quorum are set. + /// @param quorumNumber The quorum number being configured. + /// @param rateLimitWindow The new time window for rate limiting. + /// @param ejectableStakePercent The new percentage of stake that can be ejected. event QuorumEjectionParamsSet( uint8 quorumNumber, uint32 rateLimitWindow, uint16 ejectableStakePercent ); - ///@notice Emitted when an operator is ejected + + /// @notice Emitted when an operator is ejected. + /// @param operatorId The unique identifier of the ejected operator. + /// @param quorumNumber The quorum number the operator was ejected from. event OperatorEjected(bytes32 operatorId, uint8 quorumNumber); - ///@notice Emitted when operators are ejected for a quroum + + /// @notice Emitted when operators are ejected for a quorum. + /// @param ejectedOperators Number of operators that were ejected. + /// @param ratelimitHit Whether the ejection rate limit was reached. event QuorumEjection(uint32 ejectedOperators, bool ratelimitHit); +} + +interface IEjectionManager is IEjectionManagerErrors, IEjectionManagerEvents { + /// STATE + + // TODO - /** - * @notice Ejects operators from the AVSs registryCoordinator under a ratelimit - * @param _operatorIds The ids of the operators to eject for each quorum - */ + /// @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 (IRegistryCoordinator); + + /// @notice Returns the address of the stake registry contract. + /// @return The address of the stake registry. + /// @dev This value is immutable and set during contract construction. + function stakeRegistry() external view returns (IStakeRegistry); + + /// @notice Returns whether `ejector` is authorized to eject operators under a rate limit. + /// @param ejector The address to check. + /// @return Whether the address is authorized to eject operators. + function isEjector( + address ejector + ) external view returns (bool); + + /// @notice Returns the stake ejection at `index` for quorum `quorumNumber`. + /// @param quorumNumber The quorum number to query. + /// @param index The index in the ejection history. + /// @return timestamp The timestamp of the ejection. + /// @return stakeEjected The amount of stake ejected. + function stakeEjectedForQuorum( + uint8 quorumNumber, + uint256 index + ) external view returns (uint256 timestamp, uint256 stakeEjected); + + /// @notice Returns the rate limit parameters for quorum `quorumNumber`. + /// @param quorumNumber The quorum number to query. + /// @return rateLimitWindow The time window to track ejection rate (in seconds). + /// @return ejectableStakePercent The maximum percentage of stake that can be ejected per window (in BIPS). + function quorumEjectionParams( + uint8 quorumNumber + ) external view returns (uint32 rateLimitWindow, uint16 ejectableStakePercent); + + /// ACTIONS + + /// @notice Ejects operators specified in `operatorIds` from the AVS's RegistryCoordinator under a rate limit. + /// @param operatorIds The ids of the operators to eject for each quorum. + /// @dev This function will eject as many operators as possible prioritizing operators at the lower index. + /// @dev The owner can eject operators without recording of stake ejection. function ejectOperators( - bytes32[][] memory _operatorIds + bytes32[][] memory operatorIds ) external; - /** - * @notice Sets the ratelimit parameters for a quorum - * @param _quorumNumber The quorum number to set the ratelimit parameters for - * @param _quorumEjectionParams The quorum ratelimit parameters to set for the given quorum - */ + /// @notice Sets the rate limit parameters for quorum `quorumNumber` to `quorumEjectionParams`. + /// @param quorumNumber The quorum number to set the rate limit parameters for. + /// @param quorumEjectionParams The quorum rate limit parameters to set. function setQuorumEjectionParams( - uint8 _quorumNumber, - QuorumEjectionParams memory _quorumEjectionParams + uint8 quorumNumber, + QuorumEjectionParams memory quorumEjectionParams ) external; - /** - * @notice Sets the address permissioned to eject operators under a ratelimit - * @param _ejector The address to permission - */ - function setEjector(address _ejector, bool _status) external; + /// @notice Sets whether address `ejector` is permissioned to eject operators under a rate limit to `status`. + /// @param ejector The address to permission. + /// @param status The status to set for the given address. + function setEjector(address ejector, bool status) external; + + /// VIEW - /** - * @notice Returns the amount of stake that can be ejected for a quorum at the current block.timestamp - * @param _quorumNumber The quorum number to view ejectable stake for - */ + /// @notice Returns the amount of stake that can be ejected for quorum `quorumNumber` at the current block.timestamp. + /// @param quorumNumber The quorum number to view ejectable stake for. + /// @return The amount of stake that can be ejected. function amountEjectableForQuorum( - uint8 _quorumNumber + uint8 quorumNumber ) external view returns (uint256); } diff --git a/src/interfaces/IIndexRegistry.sol b/src/interfaces/IIndexRegistry.sol index 08b963ad..f58cd7bc 100644 --- a/src/interfaces/IIndexRegistry.sol +++ b/src/interfaces/IIndexRegistry.sol @@ -1,119 +1,151 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IRegistry} from "./IRegistry.sol"; - interface IIndexRegistryErrors { - /// @dev Thrown when a function is called by an address that is not the RegistryCoordinator + /// @notice Thrown when a function is called by an address that is not the RegistryCoordinator. error OnlyRegistryCoordinator(); - /// @dev Thrown when a quorum has 0 length history and thus does not exist + /// @notice Thrown when attempting to query a quorum that has no history. error QuorumDoesNotExist(); - /// @dev Thrown when an operatorId is not found in the registry at a given block number + /// @notice Thrown when attempting to look up an operator that does not exist at the specified block number. error OperatorIdDoesNotExist(); } -/** - * @title Interface for a `Registry`-type contract that keeps track of an ordered list of operators for up to 256 quorums. - * @author Layr Labs, Inc. - */ -interface IIndexRegistry is IRegistry, IIndexRegistryErrors { - // EVENTS - - // emitted when an operator's index in the ordered operator list for the quorum with number `quorumNumber` is updated - event QuorumIndexUpdate( - bytes32 indexed operatorId, uint8 quorumNumber, uint32 newOperatorIndex - ); - - // DATA STRUCTURES - - // struct used to give definitive ordering to operators at each blockNumber. +interface IIndexRegistryTypes { + /// @notice Represents an update to an operator's status at a specific index. + /// @param fromBlockNumber The block number from which this update takes effect. + /// @param operatorId The unique identifier of the operator. struct OperatorUpdate { - // blockNumber number from which `operatorIndex` was the operators index - // the operator's index is the first entry such that `blockNumber >= entry.fromBlockNumber` uint32 fromBlockNumber; - // the operator at this index bytes32 operatorId; } - // struct used to denote the number of operators in a quorum at a given blockNumber + /// @notice Represents an update to the total number of operators in a quorum. + /// @param fromBlockNumber The block number from which this update takes effect. + /// @param numOperators The total number of operators after the update. struct QuorumUpdate { - // The total number of operators at a `blockNumber` is the first entry such that `blockNumber >= entry.fromBlockNumber` uint32 fromBlockNumber; - // The number of operators at `fromBlockNumber` uint32 numOperators; } +} - /** - * @notice Registers the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. - * @param operatorId is the id of the operator that is being registered - * @param quorumNumbers is the quorum numbers the operator is registered for - * @return numOperatorsPerQuorum is a list of the number of operators (including the registering operator) in each of the quorums the operator is registered for - * @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 - */ +interface IIndexRegistryEvents is IIndexRegistryTypes { + /// @notice Emitted when an operator's index in a quorum is updated. + /// @param operatorId The unique identifier of the operator. + /// @param quorumNumber The identifier of the quorum. + /// @param newOperatorIndex The new index assigned to the operator. + event QuorumIndexUpdate( + bytes32 indexed operatorId, uint8 quorumNumber, uint32 newOperatorIndex + ); +} + +interface IIndexRegistry is IIndexRegistryErrors, IIndexRegistryEvents { + /// @notice Returns the special identifier used to indicate a non-existent operator. + /// @return The bytes32 constant OPERATOR_DOES_NOT_EXIST_ID. + function OPERATOR_DOES_NOT_EXIST_ID() external pure returns (bytes32); + + /// @notice Returns the address of the RegistryCoordinator contract. + /// @return The address of the RegistryCoordinator. + function registryCoordinator() external view returns (address); + + /// @notice Returns the current index of an operator with ID `operatorId` in quorum `quorumNumber`. + /// @dev This mapping is NOT updated when an operator is deregistered, + /// so it's possible that an index retrieved from this mapping is inaccurate. + /// If you're querying for an operator that might be deregistered, ALWAYS + /// check this index against the latest `_operatorIndexHistory` entry. + /// @param quorumNumber The identifier of the quorum. + /// @param operatorId The unique identifier of the operator. + /// @return The current index of the operator. + function currentOperatorIndex( + uint8 quorumNumber, + bytes32 operatorId + ) external view returns (uint32); + + // ACTIONS + + /// @notice Registers the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. + /// @param operatorId The unique identifier of the operator. + /// @param quorumNumbers The quorum numbers to register for. + /// @return An array containing the updated number of operators per quorum. + /// @dev Access restricted to the RegistryCoordinator. + /// @dev Preconditions: + /// 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( bytes32 operatorId, bytes calldata quorumNumbers ) external returns (uint32[] memory); - /** - * @notice Deregisters the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. - * @param operatorId is the id of the operator that is being deregistered - * @param quorumNumbers is the quorum numbers the operator is deregistered for - * @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 - */ + /// @notice Deregisters the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`. + /// @param operatorId The unique identifier of the operator. + /// @param quorumNumbers The quorum numbers to deregister from. + /// @dev Access restricted to the RegistryCoordinator. + /// @dev Preconditions: + /// 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 calldata quorumNumbers) external; - /** - * @notice Initialize a quorum by pushing its first quorum update - * @param quorumNumber The number of the new quorum - */ + /// @notice Initializes a new quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum to initialize. function initializeQuorum( uint8 quorumNumber ) external; - /// @notice Returns the OperatorUpdate entry for the specified `operatorIndex` and `quorumNumber` at the specified `arrayIndex` + // VIEW + + /// @notice Returns the operator update at index `arrayIndex` for operator at index `operatorIndex` in quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @param operatorIndex The index of the operator. + /// @param arrayIndex The index in the update history. + /// @return The operator update entry. function getOperatorUpdateAtIndex( uint8 quorumNumber, uint32 operatorIndex, uint32 arrayIndex ) external view returns (OperatorUpdate memory); - /// @notice Returns the QuorumUpdate entry for the specified `quorumNumber` at the specified `quorumIndex` + /// @notice Returns the quorum update at index `quorumIndex` for quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @param quorumIndex The index in the quorum's update history. + /// @return The quorum update entry. function getQuorumUpdateAtIndex( uint8 quorumNumber, uint32 quorumIndex ) external view returns (QuorumUpdate memory); - /// @notice Returns the most recent OperatorUpdate entry for the specified quorumNumber and operatorIndex - function getLatestOperatorUpdate( - uint8 quorumNumber, - uint32 operatorIndex - ) external view returns (OperatorUpdate memory); - - /// @notice Returns the most recent QuorumUpdate entry for the specified quorumNumber + /// @notice Returns the latest quorum update for quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @return The most recent quorum update. function getLatestQuorumUpdate( uint8 quorumNumber ) external view returns (QuorumUpdate memory); - /// @notice Returns the current number of operators of this service for `quorumNumber`. - function totalOperatorsForQuorum( - uint8 quorumNumber - ) external view returns (uint32); + /// @notice Returns the latest operator update for operator at index `operatorIndex` in quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @param operatorIndex The index of the operator. + /// @return The most recent operator update. + function getLatestOperatorUpdate( + uint8 quorumNumber, + uint32 operatorIndex + ) external view returns (OperatorUpdate memory); - /// @notice Returns an ordered list of operators of the services for the given `quorumNumber` at the given `blockNumber` + /// @notice Returns the list of operators in quorum `quorumNumber` at block `blockNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @param blockNumber The block number to query. + /// @return An array of operator IDs. function getOperatorListAtBlockNumber( uint8 quorumNumber, uint32 blockNumber ) external view returns (bytes32[] memory); + + /// @notice Returns the total number of operators in quorum `quorumNumber`. + /// @param quorumNumber The identifier of the quorum. + /// @return The total number of operators. + function totalOperatorsForQuorum( + uint8 quorumNumber + ) external view returns (uint32); } diff --git a/src/interfaces/IRegistry.sol b/src/interfaces/IRegistry.sol deleted file mode 100644 index 8a483cba..00000000 --- a/src/interfaces/IRegistry.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -/** - * @title Minimal interface for a `Registry`-type contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice Functions related to the registration process itself have been intentionally excluded - * because their function signatures may vary significantly. - */ -interface IRegistry { - function registryCoordinator() external view returns (address); -} diff --git a/src/interfaces/IRegistryCoordinator.sol b/src/interfaces/IRegistryCoordinator.sol index 3a7fcfd7..317a050c 100644 --- a/src/interfaces/IRegistryCoordinator.sol +++ b/src/interfaces/IRegistryCoordinator.sol @@ -1,218 +1,553 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; +import {IAllocationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; import {IServiceManager} from "./IServiceManager.sol"; -import {IBLSApkRegistry} from "./IBLSApkRegistry.sol"; -import {IStakeRegistry} from "./IStakeRegistry.sol"; +import {IBLSApkRegistry, IBLSApkRegistryTypes} from "./IBLSApkRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./IStakeRegistry.sol"; import {IIndexRegistry} from "./IIndexRegistry.sol"; import {BN254} from "../libraries/BN254.sol"; interface IRegistryCoordinatorErrors { + /// @notice Thrown when array lengths in input parameters don't match. error InputLengthMismatch(); + /// @notice Thrown when M2 operations are attempted while operator sets are enabled. error OperatorSetsEnabled(); + /// @notice Thrown when operator set operations are attempted while not enabled. error OperatorSetsNotEnabled(); + /// @notice Thrown when operator set operations target an unsupported quorum. error OperatorSetsNotSupported(); + /// @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 maximum quorum count is reached. error MaxQuorumsReached(); + /// @notice Thrown when using previously used salt. error SaltAlreadyUsed(); + /// @notice Thrown when registry coordinator signature is expired. error RegistryCoordinatorSignatureExpired(); + /// @notice Thrown when churn approver salt is already used. error ChurnApproverSaltUsed(); + /// @notice Thrown when operators or quorums list is not sorted ascending. error NotSorted(); } -/** - * @title Interface for a contract that coordinates between various registries for an AVS. - * @author Layr Labs, Inc. - */ -interface IRegistryCoordinator is IRegistryCoordinatorErrors { - // EVENTS - - /// Emits when an operator is registered - event OperatorRegistered(address indexed operator, bytes32 indexed operatorId); - - /// Emits when an operator is deregistered - event OperatorDeregistered(address indexed operator, bytes32 indexed operatorId); - - event OperatorSetParamsUpdated(uint8 indexed quorumNumber, OperatorSetParam operatorSetParams); - - event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); - - event EjectorUpdated(address prevEjector, address newEjector); - - /// @notice emitted when all the operators for a quorum are updated at once - event QuorumBlockNumberUpdated(uint8 indexed quorumNumber, uint256 blocknumber); - - // DATA STRUCTURES +interface IRegistryCoordinatorTypes { + /// @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 { - // default is NEVER_REGISTERED NEVER_REGISTERED, REGISTERED, DEREGISTERED } - // STRUCTS - - /** - * @notice Data structure for storing info on operators - */ + /// @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 { - // the id of the operator, which is likely the keccak256 hash of the operator's public key if using BLSRegistry bytes32 operatorId; - // indicates whether the operator is actively registered for serving the middleware or not OperatorStatus status; } - /** - * @notice Data structure for storing info on quorum bitmap updates where the `quorumBitmap` is the bitmap of the - * quorums the operator is registered for starting at (inclusive)`updateBlockNumber` and ending at (exclusive) `nextUpdateBlockNumber` - * @dev nextUpdateBlockNumber is initialized to 0 for the latest update - */ + /// @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 Data structure for storing operator set params for a given quorum. Specifically the - * `maxOperatorCount` is the maximum number of operators that can be registered for the quorum, - * `kickBIPsOfOperatorStake` is the basis points of a new operator needs to have of an operator they are trying to kick from the quorum, - * and `kickBIPsOfTotalStake` is the basis points of the total stake of the quorum that an operator needs to be below to be kicked. - */ + /// @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 Data structure for the parameters needed to kick an operator from a quorum with number `quorumNumber`, used during registration churn. - * `operator` is the address of the operator to kick - */ + /// @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 Returns the operator set params for the given `quorumNumber` - function getOperatorSetParams( - uint8 quorumNumber - ) external view returns (OperatorSetParam memory); - /// @notice the Stake registry contract that will keep track of operators' stakes - function stakeRegistry() external view returns (IStakeRegistry); - /// @notice the BLS Aggregate Pubkey Registry contract that will keep track of operators' BLS aggregate pubkeys per quorum +interface IRegistryCoordinatorEvents is IRegistryCoordinatorTypes { + /// @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 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 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); +} + +interface IRegistryCoordinator is IRegistryCoordinatorErrors, IRegistryCoordinatorEvents { + /// 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 ServiceManager contract. + /// @return The ServiceManager contract interface. + function serviceManager() external view returns (IServiceManager); + + /// @notice Reference to the BLSApkRegistry contract. + /// @return The BLSApkRegistry contract interface. function blsApkRegistry() external view returns (IBLSApkRegistry); - /// @notice the index Registry contract that will keep track of operators' indexes + + /// @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 Ejects the provided operator from the provided quorums from the AVS - * @param operator is the operator to eject - * @param quorumNumbers are the quorum numbers to eject the operator from - */ - function ejectOperator(address operator, bytes calldata quorumNumbers) external; + /// @notice Reference to the AllocationManager contract. + /// @return The AllocationManager contract interface. + function allocationManager() external view returns (IAllocationManager); - /// @notice Returns the number of quorums the registry coordinator has created + /// STORAGE + + /// @notice The total number of quorums that have been created. + /// @return The count of quorums. function quorumCount() external view returns (uint8); - /// @notice Returns the operator struct for the given `operator` + /// @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 Gets the registry contract address at a specific index. + /// @param index The index in the registries array. + /// @return The registry contract address. + function registries( + uint256 index + ) external view returns (address); + + /// @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); + + /// @notice Indicates if the AVS is using operator sets. + /// @return True if operator sets are enabled, false otherwise. + function isOperatorSetAVS() external view returns (bool); + + /// @notice Checks if a quorum is an M2 quorum. + /// @param quorumNumber The quorum identifier. + /// @return True if the quorum is M2, false otherwise. + function isM2Quorum( + uint8 quorumNumber + ) external view returns (bool); + + /// ACTIONS + + /// @notice Initializes the registry coordinator with initial configuration. + /// @param _initialOwner The address that will own the contract. + /// @param _churnApprover The address that will approve operator churn. + /// @param _ejector The address that will have ejection privileges. + /// @param _initialPausedStatus The initial pause configuration. + /// @param _operatorSetParams Parameters for operator set configuration per quorum. + /// @param _minimumStakes Minimum stake requirements per quorum. + /// @param _strategyParams Strategy configurations per quorum. + /// @param _stakeTypes Type of stake tracking per quorum. + /// @param _lookAheadPeriods Look ahead periods for slashable stake calculation. + function initialize( + address _initialOwner, + address _churnApprover, + address _ejector, + uint256 _initialPausedStatus, + OperatorSetParam[] memory _operatorSetParams, + uint96[] memory _minimumStakes, + IStakeRegistryTypes.StrategyParams[][] memory _strategyParams, + IStakeRegistryTypes.StakeType[] memory _stakeTypes, + uint32[] memory _lookAheadPeriods + ) external; + + /// @notice Registers an operator for service in specified quorums. If any quorum exceeds its maximum + /// operator capacity after the operator is registered, this method will fail. + /// @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for + /// @param socket is the socket of the operator (typically an IP address) + /// @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership + /// @param operatorSignature is the signature of the operator used by the AVS to register the operator in the delegation manager + /// @dev `params` is ignored if the caller has previously registered a public key + /// @dev `operatorSignature` is ignored if the operator's status is already REGISTERED + function registerOperator( + bytes memory quorumNumbers, + string memory socket, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external; + + /// @notice Registers an operator while replacing existing operators in full quorums. If any quorum reaches its maximum operator + /// capacity, `operatorKickParams` is used to replace an old operator with the new one. + /// @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for + /// @param socket is the socket of the operator (typically an IP address) + /// @param params contains the G1 & G2 public keys of the operator, and a signature proving their ownership + /// @param operatorKickParams used to determine which operator is removed to maintain quorum capacity as the + /// operator registers for quorums + /// @param churnApproverSignature is the signature of the churnApprover over the `operatorKickParams` + /// @param operatorSignature is the signature of the operator used by the AVS to register the operator in the delegation manager + /// @dev `params` is ignored if the caller has previously registered a public key + /// @dev `operatorSignature` is ignored if the operator's status is already REGISTERED + function registerOperatorWithChurn( + bytes calldata quorumNumbers, + string memory socket, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, + OperatorKickParam[] memory operatorKickParams, + ISignatureUtils.SignatureWithSaltAndExpiry memory churnApproverSignature, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external; + + /// @notice Deregisters the caller from one or more quorums. The operator will be removed from all registry contracts + /// and their quorum bitmap will be updated accordingly. If the operator is deregistered from all quorums, their status + /// will be updated to DEREGISTERED. + /// @param quorumNumbers is an ordered byte array containing the quorum numbers being deregistered from + /// @dev Will revert if operator is not currently registered for any of the specified quorums + function deregisterOperator( + bytes memory quorumNumbers + ) external; + + /// @notice Checks if the AVS is using operator sets mode for operator management + /// @return True if operator sets are enabled, false if using the legacy registration system + function isUsingOperatorSets() external view returns (bool); + + /// @notice Enables operator sets mode for the AVS. Once enabled, this cannot be disabled. + /// @dev When enabled, all existing quorums are marked as M2 quorums and future quorums must be explicitly + /// created as either M2 or operator set quorums + function enableOperatorSets() external; + + /// @notice Registers an operator through the allocation manager for operator set quorums + /// @param operator The operator address to register + /// @param operatorSetIds The operator set IDs to register for (corresponds to quorum numbers) + /// @param data Additional registration data containing the operator's socket and BLS public key parameters + /// @dev Can only be called by the allocation manager + /// @dev Will revert if operator sets are not enabled or if registering for M2 quorums + function registerOperator( + address operator, + uint32[] memory operatorSetIds, + bytes memory data + ) external; + + /// @notice Deregisters an operator through the allocation manager from operator set quorums + /// @param operator The operator address to deregister + /// @param operatorSetIds The operator set IDs to deregister from (corresponds to quorum numbers) + /// @dev Can only be called by the allocation manager + /// @dev Will revert if operator sets are not enabled or if deregistering from M2 quorums + function deregisterOperator(address operator, uint32[] memory operatorSetIds) external; + + /// @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 + 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. + /// @param operatorsPerQuorum for each quorum in `quorumNumbers`, this has a corresponding list of operators to update + /// @param quorumNumbers is an ordered byte array containing the quorum numbers being updated + /// @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 + /// @dev Stakes are queried from the Eigenlayer core DelegationManager contract + /// @dev Will revert if an operator registers/deregisters for any quorum in `quorumNumbers` after transaction broadcast but before execution + 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; + + /// VIEW + + /// @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 operatorId for the given `operator` + /// @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 for the given `operatorId` + /// @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 operator); + ) external view returns (address); - /// @notice Returns the status for the given `operator` + /// @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 (IRegistryCoordinator.OperatorStatus); - - /// @notice Returns the indices of the quorumBitmaps for the provided `operatorIds` at the given `blockNumber` + ) 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 the given `operatorId` at the given `blockNumber` via the `index` - * @dev reverts if `index` is incorrect - */ + /// @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 the `index`th entry in the operator with `operatorId`'s bitmap history + /// @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 the given `operatorId` + /// @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 length of the quorum bitmap history for the given `operatorId` + /// @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 Returns the registry at the desired index - function registries( - uint256 - ) external view returns (address); - - /// @notice Returns the number of registries + /// @notice Returns the number of registry contracts managed by this coordinator + /// @return The count of registry contracts (typically 3: stake, BLS, and index) function numRegistries() external view returns (uint256); - /// @notice Returns whether a quorum is an M2 quorum - /// @param quorumNumber The quorum number to check - /// @return True if the quorum is an M2 quorum - function isM2Quorum( - uint8 quorumNumber - ) external view returns (bool); - - /// @notice Returns whether the AVS is an operator set AVS - /// @return True if the AVS is an operator set AVS - function isOperatorSetAVS() external view returns (bool); + /// @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 is the address of the operator registering their BLS public key - */ + /// @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 blocknumber the quorum was last updated all at once for all operators - function quorumUpdateBlockNumber( - uint8 quorumNumber - ) external view returns (uint256); - - /// @notice The owner of the registry coordinator + /// @notice Returns the address of the contract owner + /// @return The owner's address + /// @dev The owner can update contract configuration and create new quorums function owner() external view returns (address); - - function serviceManager() external view returns (IServiceManager); } diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index 28d9c2db..033cd416 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -13,93 +13,73 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol"; interface IServiceManagerErrors { - /// @dev Thrown when a function is called by an address that is not the RegistryCoordinator + /// @notice Thrown when a function is called by an address that is not the RegistryCoordinator. error OnlyRegistryCoordinator(); - /// @dev Thrown when a function is called by an address that is not the RewardsInitiator + /// @notice Thrown when a function is called by an address that is not the RewardsInitiator. error OnlyRewardsInitiator(); - /// @dev Thrown when a function is called by an address that is not the Slasher + /// @notice Thrown when a function is called by an address that is not the StakeRegistry. error OnlyStakeRegistry(); - /// @dev Thrown when a function is called by an address that is not the Slasher + /// @notice Thrown when a function is called by an address that is not the Slasher. error OnlySlasher(); - /// @dev Thrown when a slashing proposal delay has not been met yet. + /// @notice Thrown when a slashing proposal delay has not been met yet. error DelayPeriodNotPassed(); } -/** - * @title Minimal interface for a ServiceManager-type contract that forms the single point for an AVS to push updates to EigenLayer - * @author Layr Labs, Inc. - */ -interface IServiceManager is IServiceManagerUI, IServiceManagerErrors { - // EVENTS +interface IServiceManagerEvents { + /// @notice Emitted when the rewards initiator address is updated. + /// @param prevRewardsInitiator The previous rewards initiator address. + /// @param newRewardsInitiator The new rewards initiator address. event RewardsInitiatorUpdated(address prevRewardsInitiator, address newRewardsInitiator); +} - /** - * @notice Creates a new rewards submission to the EigenLayer RewardsCoordinator contract, to be split amongst the - * set of stakers delegated to operators who are registered to this `avs` - * @param rewardsSubmissions The rewards submissions being created - * @dev Only callable by the permissioned rewardsInitiator address - * @dev The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION` - * @dev The tokens are sent to the `RewardsCoordinator` contract - * @dev Strategies must be in ascending order of addresses to check for duplicates - * @dev This function will revert if the `rewardsSubmission` is malformed, - * e.g. if the `strategies` and `weights` arrays are of non-equal lengths - */ +interface IServiceManager is IServiceManagerUI, IServiceManagerErrors, IServiceManagerEvents { + /// @notice Creates a new rewards submission to the EigenLayer RewardsCoordinator contract. + /// @dev Only callable by the permissioned rewardsInitiator address. + /// @dev The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION`. + /// @dev The tokens are sent to the `RewardsCoordinator` contract. + /// @dev Strategies must be in ascending order of addresses to check for duplicates. + /// @dev This function will revert if the `rewardsSubmission` is malformed, + /// e.g. if the `strategies` and `weights` arrays are of non-equal lengths. + /// @param rewardsSubmissions The rewards submissions to be split amongst the set of stakers + /// delegated to operators who are registered to this `avs`. function createAVSRewardsSubmission( IRewardsCoordinator.RewardsSubmission[] calldata rewardsSubmissions ) external; - /** - * - * PERMISSIONCONTROLLER FUNCTIONS - * - */ - /** - * @notice Calls `addPendingAdmin` on the `PermissionController` contract - * with `account` being the address of this contract. - * @param admin The address of the admin to add - * @dev Only callable by the owner of the contract - */ + /// @notice PERMISSIONCONTROLLER FUNCTIONS + + /// @notice Calls `addPendingAdmin` on the `PermissionController` contract. + /// @dev Only callable by the owner of the contract. + /// @param admin The address of the admin to add. function addPendingAdmin( address admin ) external; - /** - * @notice Calls `removePendingAdmin` on the `PermissionController` contract - * with `account` being the address of this contract. - * @param pendingAdmin The address of the pending admin to remove - * @dev Only callable by the owner of the contract - */ + /// @notice Calls `removePendingAdmin` on the `PermissionController` contract. + /// @dev Only callable by the owner of the contract. + /// @param pendingAdmin The address of the pending admin to remove. function removePendingAdmin( address pendingAdmin ) external; - /** - * @notice Calls `removeAdmin` on the `PermissionController` contract - * with `account` being the address of this contract. - * @param admin The address of the admin to remove - * @dev Only callable by the owner of the contract - */ + /// @notice Calls `removeAdmin` on the `PermissionController` contract. + /// @dev Only callable by the owner of the contract. + /// @param admin The address of the admin to remove. function removeAdmin( address admin ) external; - /** - * @notice Calls `setAppointee` on the `PermissionController` contract - * with `account` being the address of this contract. - * @param appointee The address of the appointee to set - * @param target The address of the target to set the appointee for - * @param selector The function selector to set the appointee for - * @dev Only callable by the owner of the contract - */ + /// @notice Calls `setAppointee` on the `PermissionController` contract. + /// @dev Only callable by the owner of the contract. + /// @param appointee The address of the appointee to set. + /// @param target The address of the target to set the appointee for. + /// @param selector The function selector to set the appointee for. function setAppointee(address appointee, address target, bytes4 selector) external; - /** - * @notice Calls `removeAppointee` on the `PermissionController` contract - * with `account` being the address of this contract. - * @param appointee The address of the appointee to remove - * @param target The address of the target to remove the appointee for - * @param selector The function selector to remove the appointee for - * @dev Only callable by the owner of the contract - */ + /// @notice Calls `removeAppointee` on the `PermissionController` contract. + /// @dev Only callable by the owner of the contract. + /// @param appointee The address of the appointee to remove. + /// @param target The address of the target to remove the appointee for. + /// @param selector The function selector to remove the appointee for. function removeAppointee(address appointee, address target, bytes4 selector) external; } diff --git a/src/interfaces/IServiceManagerUI.sol b/src/interfaces/IServiceManagerUI.sol index 558dca85..3f520ea5 100644 --- a/src/interfaces/IServiceManagerUI.sol +++ b/src/interfaces/IServiceManagerUI.sol @@ -3,63 +3,51 @@ pragma solidity >=0.5.0; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; -/** - * @title Minimal interface for a ServiceManager-type contract that AVS ServiceManager contracts must implement - * for eigenlabs to be able to index their data on the AVS marketplace frontend. - * @author Layr Labs, Inc. - */ +/// @title Minimal interface for a ServiceManager-type contract that AVS ServiceManager contracts must implement +/// for eigenlabs to be able to index their data on the AVS marketplace frontend. +/// @author Layr Labs, Inc. interface IServiceManagerUI { - /** - * Metadata should follow the format outlined by this example. - * { - * "name": "EigenLabs AVS 1", - * "website": "https://www.eigenlayer.xyz/", - * "description": "This is my 1st AVS", - * "logo": "https://holesky-operator-metadata.s3.amazonaws.com/eigenlayer.png", - * "twitter": "https://twitter.com/eigenlayer" - * } - * @notice Updates the metadata URI for the AVS - * @param _metadataURI is the metadata URI for the AVS - */ + /// Metadata should follow the format outlined by this example. + /// { + /// "name": "EigenLabs AVS 1", + /// "website": "https://www.eigenlayer.xyz/", + /// "description": "This is my 1st AVS", + /// "logo": "https://holesky-operator-metadata.s3.amazonaws.com/eigenlayer.png", + /// "twitter": "https://twitter.com/eigenlayer" + /// } + /// @notice Updates the metadata URI for the AVS + /// @param metadataURI is the metadata URI for the AVS function updateAVSMetadataURI( - string memory _metadataURI + string memory metadataURI ) external; - /** - * @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator registration with the AVS - * @param operator The address of the operator to register. - * @param operatorSignature The signature, salt, and expiry of the operator's signature. - */ + /// @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator registration with the AVS + /// @param operator The address of the operator to register. + /// @param operatorSignature The signature, salt, and expiry of the operator's signature. function registerOperatorToAVS( address operator, ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature ) external; - /** - * @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator deregistration from the AVS - * @param operator The address of the operator to deregister. - */ + /// @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator deregistration from the AVS + /// @param operator The address of the operator to deregister. function deregisterOperatorFromAVS( address operator ) external; - /** - * @notice Returns the list of strategies that the operator has potentially restaked on the AVS - * @param operator The address of the operator to get restaked strategies for - * @dev This function is intended to be called off-chain - * @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness - * of each element in the returned array. The off-chain service should do that validation separately - */ + /// @notice Returns the list of strategies that the operator has potentially restaked on the AVS + /// @param operator The address of the operator to get restaked strategies for + /// @dev This function is intended to be called off-chain + /// @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness + /// of each element in the returned array. The off-chain service should do that validation separately function getOperatorRestakedStrategies( address operator ) external view returns (address[] memory); - /** - * @notice Returns the list of strategies that the AVS supports for restaking - * @dev This function is intended to be called off-chain - * @dev No guarantee is made on uniqueness of each element in the returned array. - * The off-chain service should do that validation separately - */ + /// @notice Returns the list of strategies that the AVS supports for restaking + /// @dev This function is intended to be called off-chain + /// @dev No guarantee is made on uniqueness of each element in the returned array. + /// The off-chain service should do that validation separately function getRestakeableStrategies() external view returns (address[] memory); /// @notice Returns the EigenLayer AVSDirectory contract. diff --git a/src/interfaces/ISlasher.sol b/src/interfaces/ISlasher.sol index b00fd65a..424b8178 100644 --- a/src/interfaces/ISlasher.sol +++ b/src/interfaces/ISlasher.sol @@ -5,42 +5,28 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; -interface ISlasherEvents { - event SlashingRequested( - uint256 indexed requestId, - address indexed operator, - uint32 indexed operatorSetId, - uint256[] wadsToSlash, - string description - ); - - event SlashingRequestCancelled(uint256 indexed requestId); - - event OperatorSlashed( - uint256 indexed slashingRequestId, - address indexed operator, - uint32 indexed operatorSetId, - uint256[] wadsToSlash, - string description - ); -} - interface ISlasherErrors { - /// @dev Thrown when the caller is not the veto committee + /// @notice Thrown when a caller without veto committee privileges attempts a restricted operation. error OnlyVetoCommittee(); - /// @dev Thrown when the caller is not the slasher + /// @notice Thrown when a caller without slasher privileges attempts a restricted operation. error OnlySlasher(); - /// @dev Thrown when the veto period has passed + /// @notice Thrown when attempting to veto a slashing request after the veto period has expired. error VetoPeriodPassed(); - /// @dev Thrown when the veto period has not passed + /// @notice Thrown when attempting to execute a slashing request before the veto period has ended. error VetoPeriodNotPassed(); - /// @dev Thrown when the slashing request is cancelled + /// @notice Thrown when attempting to interact with a slashing request that has been cancelled. error SlashingRequestIsCancelled(); - /// @dev Thrown when the slashing request was not already requested + /// @notice Thrown when attempting to modify a slashing request that does not exist. error SlashingRequestNotRequested(); } interface ISlasherTypes { + /// @notice Represents the current status of a slashing request. + /// @dev The status of a slashing request can be one of the following: + /// - Null: Default state, no request exists. + /// - Requested: Slashing has been requested but not yet executed. + /// - Completed: Slashing has been successfully executed. + /// - Cancelled: Slashing request was cancelled by veto committee. enum SlashingStatus { Null, Requested, @@ -48,6 +34,10 @@ interface ISlasherTypes { Cancelled } + /// @notice Contains all information related to a slashing request. + /// @param params The slashing parameters from the allocation manager. + /// @param requestTimestamp The timestamp when the slashing request was created. + /// @param status The current status of the slashing request. struct SlashingRequest { IAllocationManager.SlashingParams params; uint256 requestTimestamp; @@ -55,4 +45,38 @@ interface ISlasherTypes { } } -interface ISlasher is ISlasherEvents, ISlasherTypes, ISlasherErrors {} +interface ISlasherEvents is ISlasherTypes { + /// @notice Emitted when a new slashing request is created. + /// @param requestId The unique identifier for the slashing request (indexed). + /// @param operator The address of the operator to be slashed (indexed). + /// @param operatorSetId The ID of the operator set involved (indexed). + /// @param wadsToSlash The amounts to slash from each strategy. + /// @param description A human-readable description of the slashing reason. + event SlashingRequested( + uint256 indexed requestId, + address indexed operator, + uint32 indexed operatorSetId, + uint256[] wadsToSlash, + string description + ); + + /// @notice Emitted when a slashing request is cancelled by the veto committee. + /// @param requestId The unique identifier of the cancelled request (indexed). + event SlashingRequestCancelled(uint256 indexed requestId); + + /// @notice Emitted when an operator is successfully slashed. + /// @param slashingRequestId The ID of the executed slashing request (indexed). + /// @param operator The address of the slashed operator (indexed). + /// @param operatorSetId The ID of the operator set involved (indexed). + /// @param wadsToSlash The amounts slashed from each strategy. + /// @param description A human-readable description of why the operator was slashed. + event OperatorSlashed( + uint256 indexed slashingRequestId, + address indexed operator, + uint32 indexed operatorSetId, + uint256[] wadsToSlash, + string description + ); +} + +interface ISlasher is ISlasherErrors, ISlasherEvents {} diff --git a/src/interfaces/ISocketUpdater.sol b/src/interfaces/ISocketUpdater.sol deleted file mode 100644 index 921b1a46..00000000 --- a/src/interfaces/ISocketUpdater.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity ^0.8.27; - -/** - * @title Interface for an `ISocketUpdater` where operators can update their sockets. - * @author Layr Labs, Inc. - */ -interface ISocketUpdater { - // EVENTS - - event OperatorSocketUpdate(bytes32 indexed operatorId, string socket); - - // FUNCTIONS - - /** - * @notice Updates the socket of the msg.sender given they are a registered operator - * @param socket is the new socket of the operator - */ - function updateSocket( - string memory socket - ) external; -} diff --git a/src/interfaces/IStakeRegistry.sol b/src/interfaces/IStakeRegistry.sol index a9d3d5a3..81fe727e 100644 --- a/src/interfaces/IStakeRegistry.sol +++ b/src/interfaces/IStakeRegistry.sol @@ -5,265 +5,338 @@ import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; -import {IRegistry} from "./IRegistry.sol"; - -enum StakeType { - TOTAL_DELEGATED, - TOTAL_SLASHABLE -} - +/// @notice Interface containing all error definitions for the StakeRegistry contract. interface IStakeRegistryErrors { - /// @dev Thrown when the caller is not the registry coordinator + /// @notice Thrown when a function is called by someone other than the registry coordinator. error OnlyRegistryCoordinator(); - /// @dev Thrown when the caller is not the owner of the registry coordinator + /// @notice Thrown when a function is called by someone other than the registry coordinator owner. error OnlyRegistryCoordinatorOwner(); - /// @dev Thrown when the stake is below the minimum required for a quorum + /// @notice Thrown when an operator's stake falls below the minimum requirement for a quorum. error BelowMinimumStakeRequirement(); - /// @dev Thrown when a quorum being created already exists. + /// @notice Thrown when attempting to create a quorum that already exists. error QuorumAlreadyExists(); - /// @dev Thrown when a quorum does not exist. + /// @notice Thrown when attempting to interact with a quorum that does not exist. error QuorumDoesNotExist(); - /// @dev Thrown when two array parameters have mismatching lengths. + /// @notice Thrown when two array parameters have mismatching lengths. error InputArrayLengthMismatch(); - /// @dev Thrown when input arrays length is zero. + /// @notice Thrown when an input array has zero length. error InputArrayLengthZero(); - /// @dev Thrown when a duplicate strategy is provided in input array. + /// @notice Thrown when a duplicate strategy is provided in an input array. error InputDuplicateStrategy(); - /// @dev Thrown when multiplier input is zero. + /// @notice Thrown when a multiplier input is zero. error InputMultiplierZero(); - /// @dev Thrown when the blocknumber provided is not >= the provided StakeUpdate's updateBlockNumber - /// or if the blocknumber provided is not the nextUpdateBlockNumber + /// @notice Thrown when the provided block number is invalid for the stake update. error InvalidBlockNumber(); - /// @dev Thrown when the quorum has no stake history at block number provided. + /// @notice Thrown when attempting to access stake history that doesn't exist for a quorum. error EmptyStakeHistory(); } -/** - * @title Interface for a `Registry` that keeps track of stakes of operators for up to 256 quorums. - * @author Layr Labs, Inc. - */ -interface IStakeRegistry is IRegistry, IStakeRegistryErrors { - // DATA STRUCTURES +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 struct used to store the stakes of an individual operator or the sum of all operators' stakes, for storage + /// @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 { - // the block number at which the stake amounts were updated and stored uint32 updateBlockNumber; - // the block number at which the *next update* occurred. - /// @notice This entry has the value **0** until another update takes place. uint32 nextUpdateBlockNumber; - // stake weight for the quorum uint96 stake; } - /** - * @notice In weighing a particular strategy, the amount of underlying asset for that strategy is - * multiplied by its multiplier, then divided by WEIGHTING_DIVISOR - */ + /// @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; } +} - // EVENTS - - /// @notice emitted whenever the stake of `operator` is updated +/// @notice Interface containing all event definitions for the StakeRegistry contract. +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 time(in blocks) for checking operator shares is updated + /// @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 + /// @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 + + /// @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 + + /// @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 `strategy` has been added to the array at `strategyParams[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 `strategy` has removed from the array at `strategyParams[quorumNumber]` + + /// @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 `strategy` has its `multiplier` updated in the array at `strategyParams[quorumNumber]` + + /// @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 ); +} - /** - * @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 The operator's current stake for each quorum, and 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 - */ +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, uint96[] memory); - - /** - * @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 - */ + ) 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 Initialize a new quorum created by the registry coordinator by setting strategies, weights, and minimum stake - */ - /// @notice Initialize a new quorum and push its first history update + /// @notice Called by the registry coordinator to update an operator's stake for one or more quorums. + /// @param operator The address of the operator to update. + /// @param operatorId The id of the operator to update. + /// @param quorumNumbers The quorum numbers to update the stake for. + /// @return A bitmap of quorums where the operator no longer meets the minimum stake and should be deregistered. + function updateOperatorStake( + address operator, + bytes32 operatorId, + bytes calldata quorumNumbers + ) external returns (uint192); + + /// @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 + StrategyParams[] memory strategyParams ) external; - /// @notice Initialize a new quorum and push its first history update + /// @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 + StrategyParams[] memory strategyParams ) external; - /// @notice Adds new strategies and the associated multipliers to the @param quorumNumber. + /// @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 This function is used for removing strategies and their associated weights from the - * mapping strategyParams for a specific @param quorumNumber. - * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise - * the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove - */ + /// @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 This function is used for modifying the weights of strategies that are already in the - * mapping strategyParams for a specific - * @param quorumNumber is the quorum number to change the strategy for - * @param strategyIndices are the indices of the strategies to change - * @param newMultipliers are the new multipliers for the strategies - */ + /// @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; - /// @notice Constant used as a divisor in calculating weights. - function WEIGHTING_DIVISOR() external pure returns (uint256); + /// VIEW - /// @notice Returns the EigenLayer delegation manager contract. - function delegation() external view returns (IDelegationManager); + /// @notice Returns whether a quorum is an operator set quorum. + /// @param quorumNumber The quorum number to query. + /// @return Whether the quorum is an operator set quorum. + function isOperatorSetQuorum( + uint8 quorumNumber + ) external view returns (bool); - /// @notice In order to register for a quorum i, an operator must have at least `minimumStakeForQuorum[i]` + /// @notice Returns the minimum stake requirement for a quorum `quorumNumber`. + /// @dev In order to register for a quorum i, an operator must have at least `minimumStakeForQuorum[i]`. + /// @param quorumNumber The quorum number to query. + /// @return The minimum stake requirement. function minimumStakeForQuorum( uint8 quorumNumber ) external view returns (uint96); /// @notice Returns the length of the dynamic array stored in `strategyParams[quorumNumber]`. + /// @param quorumNumber The quorum number to query. + /// @return The number of strategies for the quorum. function strategyParamsLength( uint8 quorumNumber ) external view returns (uint256); - /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` + /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum. + /// @param quorumNumber The quorum number to query. + /// @param index The index of the strategy to query. + /// @return The strategy parameters. function strategyParamsByIndex( uint8 quorumNumber, uint256 index ) external view returns (StrategyParams memory); - /** - * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. - * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` - */ + /// @notice Returns the length of the stake history for an operator in a quorum. + /// @param operatorId The id of the operator to query. + /// @param quorumNumber The quorum number to query. + /// @return The length of the stake history array. + function getStakeHistoryLength( + bytes32 operatorId, + uint8 quorumNumber + ) external view returns (uint256); + + /// @notice Computes the total weight of the operator in the specified quorum. + /// @param quorumNumber The quorum number to query. + /// @param operator The operator address to query. + /// @return The total weight of the operator. + /// @dev Reverts if `quorumNumber` is greater than or equal to `quorumCount`. function weightOfOperatorForQuorum( uint8 quorumNumber, address operator ) external view returns (uint96); - /** - * @notice Returns the entire `operatorIdToStakeHistory[operatorId][quorumNumber]` array. - * @param operatorId The id of the operator of interest. - * @param quorumNumber The quorum number to get the stake for. - */ + /// @notice Returns the entire stake history array for an operator in a quorum. + /// @param operatorId The id of the operator of interest. + /// @param quorumNumber The quorum number to get the stake for. + /// @return The array of stake updates. function getStakeHistory( bytes32 operatorId, uint8 quorumNumber ) external view returns (StakeUpdate[] memory); + /// @notice Returns the length of the total stake history for a quorum. + /// @param quorumNumber The quorum number to query. + /// @return The length of the total stake history array. function getTotalStakeHistoryLength( uint8 quorumNumber ) external view returns (uint256); - /** - * @notice Returns the `index`-th entry in the dynamic array of total stake, `totalStakeHistory` for quorum `quorumNumber`. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `totalStakeHistory[quorumNumber]`. - */ + /// @notice Returns the stake update at the specified index in the total stake history. + /// @param quorumNumber The quorum number to query. + /// @param index The index to query. + /// @return The stake update at the specified index. function getTotalStakeUpdateAtIndex( uint8 quorumNumber, uint256 index ) external view returns (StakeUpdate memory); - /// @notice Returns the indices of the operator stakes for the provided `quorumNumber` at the given `blockNumber` + /// @notice Returns the index of the operator's stake update at the specified block number. + /// @param operatorId The id of the operator to query. + /// @param quorumNumber The quorum number to query. + /// @param blockNumber The block number to query. + /// @return The index of the stake update. function getStakeUpdateIndexAtBlockNumber( bytes32 operatorId, uint8 quorumNumber, uint32 blockNumber ) external view returns (uint32); - /// @notice Returns the indices of the total stakes for the provided `quorumNumbers` at the given `blockNumber` + /// @notice Returns the indices of total stakes for the provided quorums at the given block number. + /// @param blockNumber The block number to query. + /// @param quorumNumbers The quorum numbers to query. + /// @return The array of stake update indices. function getTotalStakeIndicesAtBlockNumber( uint32 blockNumber, bytes calldata quorumNumbers ) external view returns (uint32[] memory); - /** - * @notice Returns the `index`-th entry in the `operatorIdToStakeHistory[operatorId][quorumNumber]` array. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorIdToStakeHistory[operatorId][quorumNumber]`. - * @dev Function will revert if `index` is out-of-bounds. - */ + /// @notice Returns the stake update at the specified index for an operator in a quorum. + /// @param quorumNumber The quorum number to query. + /// @param operatorId The id of the operator to query. + /// @param index The index to query. + /// @return The stake update at the specified index. + /// @dev Function will revert if `index` is out-of-bounds. function getStakeUpdateAtIndex( uint8 quorumNumber, bytes32 operatorId, uint256 index ) external view returns (StakeUpdate memory); - /** - * @notice Returns the most recent stake weight for the `operatorId` for a certain quorum - * @dev Function returns an StakeUpdate struct with **every entry equal to 0** in the event that the operator has no stake history - */ + /// @notice Returns the most recent stake update for an operator in a quorum. + /// @param operatorId The id of the operator to query. + /// @param quorumNumber The quorum number to query. + /// @return The most recent stake update. + /// @dev Returns a StakeUpdate struct with all entries equal to 0 if the operator has no stake history. function getLatestStakeUpdate( bytes32 operatorId, uint8 quorumNumber ) external view returns (StakeUpdate memory); - /** - * @notice Returns the stake weight corresponding to `operatorId` for quorum `quorumNumber`, at the - * `index`-th entry in the `operatorIdToStakeHistory[operatorId][quorumNumber]` array if the entry - * corresponds to the operator's stake at `blockNumber`. Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorIdToStakeHistory[operatorId][quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - * @dev used the BLSSignatureChecker to get past stakes of signing operators - */ + /// @notice Returns the stake at the specified block number and index for an operator in a quorum. + /// @param quorumNumber The quorum number to query. + /// @param blockNumber The block number to query. + /// @param operatorId The id of the operator to query. + /// @param index The index to query. + /// @return The stake amount. + /// @dev Function will revert if `index` is out-of-bounds. + /// @dev Used by the BLSSignatureChecker to get past stakes of signing operators. function getStakeAtBlockNumberAndIndex( uint8 quorumNumber, uint32 blockNumber, @@ -271,58 +344,45 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { uint256 index ) external view returns (uint96); - /** - * @notice Returns the total stake weight for quorum `quorumNumber`, at the `index`-th entry in the - * `totalStakeHistory[quorumNumber]` array if the entry corresponds to the total stake at `blockNumber`. - * Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `totalStakeHistory[quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - * @dev used the BLSSignatureChecker to get past stakes of signing operators - */ + /// @notice Returns the total stake at the specified block number and index for a quorum. + /// @param quorumNumber The quorum number to query. + /// @param blockNumber The block number to query. + /// @param index The index to query. + /// @return The total stake amount. + /// @dev Function will revert if `index` is out-of-bounds. + /// @dev Used by the BLSSignatureChecker to get past stakes of signing operators. function getTotalStakeAtBlockNumberFromIndex( uint8 quorumNumber, uint32 blockNumber, uint256 index ) external view returns (uint96); - /** - * @notice Returns the most recent stake weight for the `operatorId` for quorum `quorumNumber` - * @dev Function returns weight of **0** in the event that the operator has no stake history - */ + /// @notice Returns the current stake for an operator in a quorum. + /// @param operatorId The id of the operator to query. + /// @param quorumNumber The quorum number to query. + /// @return The current stake amount. + /// @dev Returns 0 if the operator has no stake history. function getCurrentStake( bytes32 operatorId, uint8 quorumNumber ) external view returns (uint96); - /// @notice Returns the stake of the operator for the provided `quorumNumber` at the given `blockNumber` + /// @notice Returns the stake of an operator at a specific block number. + /// @param operatorId The id of the operator to query. + /// @param quorumNumber The quorum number to query. + /// @param blockNumber The block number to query. + /// @return The stake amount at the specified block. function getStakeAtBlockNumber( bytes32 operatorId, uint8 quorumNumber, uint32 blockNumber ) external view returns (uint96); - /** - * @notice Returns the stake weight from the latest entry in `_totalStakeHistory` for quorum `quorumNumber`. - * @dev Will revert if `_totalStakeHistory[quorumNumber]` is empty. - */ + /// @notice Returns the current total stake for a quorum. + /// @param quorumNumber The quorum number to query. + /// @return The current total stake amount. + /// @dev Will revert if `_totalStakeHistory[quorumNumber]` is empty. function getCurrentTotalStake( uint8 quorumNumber ) external view returns (uint96); - - /** - * @notice Called by the registry coordinator to update an operator's stake for one - * or more quorums. - * - * If the operator no longer has the minimum stake required for a quorum, they are - * added to the - * @return A bitmap of quorums where the operator no longer meets the minimum stake - * and should be deregistered. - */ - function updateOperatorStake( - address operator, - bytes32 operatorId, - bytes calldata quorumNumbers - ) external returns (uint192); } diff --git a/src/libraries/QuorumBitmapHistoryLib.sol b/src/libraries/QuorumBitmapHistoryLib.sol index 92848aba..95a0258a 100644 --- a/src/libraries/QuorumBitmapHistoryLib.sol +++ b/src/libraries/QuorumBitmapHistoryLib.sol @@ -1,7 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IRegistryCoordinator} from "../interfaces/IRegistryCoordinator.sol"; +import { + IRegistryCoordinator, IRegistryCoordinatorTypes +} from "../interfaces/IRegistryCoordinator.sol"; /// @title QuorumBitmapHistoryLib /// @notice This library operates on the _operatorBitmapHistory in the RegistryCoordinator @@ -118,7 +120,7 @@ library QuorumBitmapHistoryLib { if (historyLength == 0) { // No prior bitmap history - push our first entry self[operatorId].push( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0, quorumBitmap: newBitmap @@ -138,7 +140,7 @@ library QuorumBitmapHistoryLib { } else { lastUpdate.nextUpdateBlockNumber = uint32(block.number); self[operatorId].push( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0, quorumBitmap: newBitmap diff --git a/src/unaudited/ECDSAServiceManagerBase.sol b/src/unaudited/ECDSAServiceManagerBase.sol index a2fa81b6..c80ba6ad 100644 --- a/src/unaudited/ECDSAServiceManagerBase.sol +++ b/src/unaudited/ECDSAServiceManagerBase.sol @@ -12,7 +12,7 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy import {IStakeRegistry} from "../interfaces/IStakeRegistry.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; -import {Quorum} from "../interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; +import {IECDSAStakeRegistryTypes} from "../interfaces/IECDSAStakeRegistry.sol"; import {ECDSAStakeRegistry} from "../unaudited/ECDSAStakeRegistry.sol"; import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol"; import {IAllocationManager} from @@ -197,7 +197,7 @@ abstract contract ECDSAServiceManagerBase is IServiceManager, OwnableUpgradeable * @return strategies An array of addresses representing the strategies in the current quorum. */ function _getRestakeableStrategies() internal view virtual returns (address[] memory) { - Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum(); + IECDSAStakeRegistryTypes.Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum(); address[] memory strategies = new address[](quorum.strategies.length); for (uint256 i = 0; i < quorum.strategies.length; i++) { strategies[i] = address(quorum.strategies[i].strategy); @@ -226,7 +226,7 @@ abstract contract ECDSAServiceManagerBase is IServiceManager, OwnableUpgradeable function _getOperatorRestakedStrategies( address _operator ) internal view virtual returns (address[] memory) { - Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum(); + IECDSAStakeRegistryTypes.Quorum memory quorum = ECDSAStakeRegistry(stakeRegistry).quorum(); uint256 count = quorum.strategies.length; IStrategy[] memory strategies = new IStrategy[](count); for (uint256 i; i < count; i++) { diff --git a/src/unaudited/ECDSAStakeRegistry.sol b/src/unaudited/ECDSAStakeRegistry.sol index edbb6778..c961c83e 100644 --- a/src/unaudited/ECDSAStakeRegistry.sol +++ b/src/unaudited/ECDSAStakeRegistry.sol @@ -1,7 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.27; -import {ECDSAStakeRegistryStorage, Quorum, StrategyParams} from "./ECDSAStakeRegistryStorage.sol"; +import { + IECDSAStakeRegistry, + ECDSAStakeRegistryStorage, + IECDSAStakeRegistryTypes +} from "./ECDSAStakeRegistryStorage.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; @@ -37,206 +41,168 @@ contract ECDSAStakeRegistry is /// @notice Initializes the contract with the given parameters. /// @param _serviceManager The address of the service manager. - /// @param _thresholdWeight The threshold weight in basis points. - /// @param _quorum The quorum struct containing the details of the quorum thresholds. + /// @param thresholdWeight The threshold weight in basis points. + /// @param quorum The quorum struct containing the details of the quorum thresholds. function initialize( address _serviceManager, - uint256 _thresholdWeight, - Quorum memory _quorum + uint256 thresholdWeight, + IECDSAStakeRegistryTypes.Quorum memory quorum ) external initializer { - __ECDSAStakeRegistry_init(_serviceManager, _thresholdWeight, _quorum); + __ECDSAStakeRegistry_init(_serviceManager, thresholdWeight, quorum); } - /// @notice Registers a new operator using a provided signature and signing key - /// @param _operatorSignature Contains the operator's signature, salt, and expiry - /// @param _signingKey The signing key to add to the operator's history + /// @notice Initializes state for the StakeRegistry + /// @param _serviceManagerAddr The AVS' ServiceManager contract's address + function __ECDSAStakeRegistry_init( + address _serviceManagerAddr, + uint256 thresholdWeight, + IECDSAStakeRegistryTypes.Quorum memory quorum + ) internal onlyInitializing { + _serviceManager = _serviceManagerAddr; + _updateStakeThreshold(thresholdWeight); + _updateQuorumConfig(quorum); + __Ownable_init(); + } + + /// @inheritdoc IECDSAStakeRegistry function registerOperatorWithSignature( - ISignatureUtils.SignatureWithSaltAndExpiry memory _operatorSignature, - address _signingKey + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature, + address signingKey ) external { - _registerOperatorWithSig(msg.sender, _operatorSignature, _signingKey); + _registerOperatorWithSig(msg.sender, operatorSignature, signingKey); } - /// @notice Deregisters an existing operator + /// @inheritdoc IECDSAStakeRegistry function deregisterOperator() external { _deregisterOperator(msg.sender); } - /** - * @notice Updates the signing key for an operator - * @dev Only callable by the operator themselves - * @param _newSigningKey The new signing key to set for the operator - */ + /// @inheritdoc IECDSAStakeRegistry function updateOperatorSigningKey( - address _newSigningKey + address newSigningKey ) external { if (!_operatorRegistered[msg.sender]) { revert OperatorNotRegistered(); } - _updateOperatorSigningKey(msg.sender, _newSigningKey); + _updateOperatorSigningKey(msg.sender, newSigningKey); } - /** - * @notice Updates the StakeRegistry's view of one or more operators' stakes adding a new entry in their history of stake checkpoints, - * @dev Queries stakes from the Eigenlayer core DelegationManager contract - * @param _operators A list of operator addresses to update - */ + /// @inheritdoc IECDSAStakeRegistry function updateOperators( - address[] memory _operators + address[] memory operators ) external { - _updateOperators(_operators); + _updateOperators(operators); } - /** - * @notice Updates the quorum configuration and the set of operators - * @dev Only callable by the contract owner. - * It first updates the quorum configuration and then updates the list of operators. - * @param _quorum The new quorum configuration, including strategies and their new weights - * @param _operators The list of operator addresses to update stakes for - */ + /// @inheritdoc IECDSAStakeRegistry function updateQuorumConfig( - Quorum memory _quorum, - address[] memory _operators + IECDSAStakeRegistryTypes.Quorum memory quorum, + address[] memory operators ) external onlyOwner { - _updateQuorumConfig(_quorum); - _updateOperators(_operators); + _updateQuorumConfig(quorum); + _updateOperators(operators); } - /// @notice Updates the weight an operator must have to join the operator set - /// @dev Access controlled to the contract owner - /// @param _newMinimumWeight The new weight an operator must have to join the operator set + /// @inheritdoc IECDSAStakeRegistry function updateMinimumWeight( - uint256 _newMinimumWeight, - address[] memory _operators + uint256 newMinimumWeight, + address[] memory operators ) external onlyOwner { - _updateMinimumWeight(_newMinimumWeight); - _updateOperators(_operators); + _updateMinimumWeight(newMinimumWeight); + _updateOperators(operators); } - /** - * @notice Sets a new cumulative threshold weight for message validation by operator set signatures. - * @dev This function can only be invoked by the owner of the contract. It delegates the update to - * an internal function `_updateStakeThreshold`. - * @param _thresholdWeight The updated threshold weight required to validate a message. This is the - * cumulative weight that must be met or exceeded by the sum of the stakes of the signatories for - * a message to be deemed valid. - */ + /// @inheritdoc IECDSAStakeRegistry function updateStakeThreshold( - uint256 _thresholdWeight + uint256 thresholdWeight ) external onlyOwner { - _updateStakeThreshold(_thresholdWeight); + _updateStakeThreshold(thresholdWeight); } - /// @notice Verifies if the provided signature data is valid for the given data hash. - /// @param _dataHash The hash of the data that was signed. - /// @param _signatureData Encoded signature data consisting of an array of operators, an array of signatures, and a reference block number. - /// @return The function selector that indicates the signature is valid according to ERC1271 standard. function isValidSignature( - bytes32 _dataHash, + bytes32 digest, bytes memory _signatureData ) external view returns (bytes4) { (address[] memory operators, bytes[] memory signatures, uint32 referenceBlock) = abi.decode(_signatureData, (address[], bytes[], uint32)); - _checkSignatures(_dataHash, operators, signatures, referenceBlock); + _checkSignatures(digest, operators, signatures, referenceBlock); return IERC1271Upgradeable.isValidSignature.selector; } - /// @notice Retrieves the current stake quorum details. - /// @return Quorum - The current quorum of strategies and weights - function quorum() external view returns (Quorum memory) { + /// @inheritdoc IECDSAStakeRegistry + function quorum() external view returns (IECDSAStakeRegistryTypes.Quorum memory) { return _quorum; } - /** - * @notice Retrieves the latest signing key for a given operator. - * @param _operator The address of the operator. - * @return The latest signing key of the operator. - */ - function getLastestOperatorSigningKey( - address _operator + /// @inheritdoc IECDSAStakeRegistry + function getLatestOperatorSigningKey( + address operator ) external view returns (address) { - return address(uint160(_operatorSigningKeyHistory[_operator].latest())); + return address(uint160(_operatorSigningKeyHistory[operator].latest())); } - /** - * @notice Retrieves the latest signing key for a given operator at a specific block number. - * @param _operator The address of the operator. - * @param _blockNumber The block number to get the operator's signing key. - * @return The signing key of the operator at the given block. - */ + /// @inheritdoc IECDSAStakeRegistry function getOperatorSigningKeyAtBlock( - address _operator, - uint256 _blockNumber + address operator, + uint256 blockNumber ) external view returns (address) { - return address(uint160(_operatorSigningKeyHistory[_operator].getAtBlock(_blockNumber))); + return address(uint160(_operatorSigningKeyHistory[operator].getAtBlock(blockNumber))); } - /// @notice Retrieves the last recorded weight for a given operator. - /// @param _operator The address of the operator. - /// @return uint256 - The latest weight of the operator. + /// @inheritdoc IECDSAStakeRegistry function getLastCheckpointOperatorWeight( - address _operator + address operator ) external view returns (uint256) { - return _operatorWeightHistory[_operator].latest(); + return _operatorWeightHistory[operator].latest(); } - /// @notice Retrieves the last recorded total weight across all operators. - /// @return uint256 - The latest total weight. + /// @inheritdoc IECDSAStakeRegistry function getLastCheckpointTotalWeight() external view returns (uint256) { return _totalWeightHistory.latest(); } - /// @notice Retrieves the last recorded threshold weight - /// @return uint256 - The latest threshold weight. + /// @inheritdoc IECDSAStakeRegistry function getLastCheckpointThresholdWeight() external view returns (uint256) { return _thresholdWeightHistory.latest(); } - /// @notice Retrieves the operator's weight at a specific block number. - /// @param _operator The address of the operator. - /// @param _blockNumber The block number to get the operator weight for the quorum - /// @return uint256 - The weight of the operator at the given block. + /// @inheritdoc IECDSAStakeRegistry function getOperatorWeightAtBlock( - address _operator, - uint32 _blockNumber + address operator, + uint32 blockNumber ) external view returns (uint256) { - return _operatorWeightHistory[_operator].getAtBlock(_blockNumber); + return _operatorWeightHistory[operator].getAtBlock(blockNumber); } - /// @notice Retrieves the total weight at a specific block number. - /// @param _blockNumber The block number to get the total weight for the quorum - /// @return uint256 - The total weight at the given block. + /// @inheritdoc IECDSAStakeRegistry function getLastCheckpointTotalWeightAtBlock( - uint32 _blockNumber + uint32 blockNumber ) external view returns (uint256) { - return _totalWeightHistory.getAtBlock(_blockNumber); + return _totalWeightHistory.getAtBlock(blockNumber); } - /// @notice Retrieves the threshold weight at a specific block number. - /// @param _blockNumber The block number to get the threshold weight for the quorum - /// @return uint256 - The threshold weight the given block. + /// @inheritdoc IECDSAStakeRegistry function getLastCheckpointThresholdWeightAtBlock( - uint32 _blockNumber + uint32 blockNumber ) external view returns (uint256) { - return _thresholdWeightHistory.getAtBlock(_blockNumber); + return _thresholdWeightHistory.getAtBlock(blockNumber); } + /// @inheritdoc IECDSAStakeRegistry function operatorRegistered( - address _operator + address operator ) external view returns (bool) { - return _operatorRegistered[_operator]; + return _operatorRegistered[operator]; } - /// @notice Returns the weight an operator must have to contribute to validating an AVS + /// @inheritdoc IECDSAStakeRegistry function minimumWeight() external view returns (uint256) { return _minimumWeight; } - /// @notice Calculates the current weight of an operator based on their delegated stake in the strategies considered in the quorum - /// @param _operator The address of the operator. - /// @return uint256 - The current weight of the operator; returns 0 if below the threshold. + /// @inheritdoc IECDSAStakeRegistry function getOperatorWeight( - address _operator + address operator ) public view returns (uint256) { StrategyParams[] memory strategyParams = _quorum.strategies; uint256 weight; @@ -244,7 +210,7 @@ contract ECDSAStakeRegistry is for (uint256 i; i < strategyParams.length; i++) { strategies[i] = strategyParams[i].strategy; } - uint256[] memory shares = DELEGATION_MANAGER.getOperatorShares(_operator, strategies); + uint256[] memory shares = DELEGATION_MANAGER.getOperatorShares(operator, strategies); for (uint256 i; i < strategyParams.length; i++) { weight += shares[i] * strategyParams[i].multiplier; } @@ -257,22 +223,7 @@ contract ECDSAStakeRegistry is } } - /// @notice Initializes state for the StakeRegistry - /// @param _serviceManagerAddr The AVS' ServiceManager contract's address - function __ECDSAStakeRegistry_init( - address _serviceManagerAddr, - uint256 _thresholdWeight, - Quorum memory _quorum - ) internal onlyInitializing { - _serviceManager = _serviceManagerAddr; - _updateStakeThreshold(_thresholdWeight); - _updateQuorumConfig(_quorum); - __Ownable_init(); - } - - /// @notice Updates the set of operators for the first quorum. - /// @param operatorsPerQuorum An array of operator address arrays, one for each quorum. - /// @dev This interface maintains compatibility with avs-sync which handles multiquorums while this registry has a single quorum + /// @inheritdoc IECDSAStakeRegistry function updateOperatorsForQuorum( address[][] memory operatorsPerQuorum, bytes memory @@ -282,138 +233,138 @@ contract ECDSAStakeRegistry is /// @dev Updates the list of operators if the provided list has the correct number of operators. /// Reverts if the provided list of operators does not match the expected total count of operators. - /// @param _operators The list of operator addresses to update. + /// @param operators The list of operator addresses to update. function _updateAllOperators( - address[] memory _operators + address[] memory operators ) internal { - if (_operators.length != _totalOperators) { + if (operators.length != _totalOperators) { revert MustUpdateAllOperators(); } - _updateOperators(_operators); + _updateOperators(operators); } /// @dev Updates the weights for a given list of operator addresses. /// When passing an operator that isn't registered, then 0 is added to their history - /// @param _operators An array of addresses for which to update the weights. + /// @param operators An array of addresses for which to update the weights. function _updateOperators( - address[] memory _operators + address[] memory operators ) internal { int256 delta; - for (uint256 i; i < _operators.length; i++) { - delta += _updateOperatorWeight(_operators[i]); + for (uint256 i; i < operators.length; i++) { + delta += _updateOperatorWeight(operators[i]); } _updateTotalWeight(delta); } /// @dev Updates the stake threshold weight and records the history. - /// @param _thresholdWeight The new threshold weight to set and record in the history. + /// @param thresholdWeight The new threshold weight to set and record in the history. function _updateStakeThreshold( - uint256 _thresholdWeight + uint256 thresholdWeight ) internal { - _thresholdWeightHistory.push(_thresholdWeight); - emit ThresholdWeightUpdated(_thresholdWeight); + _thresholdWeightHistory.push(thresholdWeight); + emit ThresholdWeightUpdated(thresholdWeight); } /// @dev Updates the weight an operator must have to join the operator set - /// @param _newMinimumWeight The new weight an operator must have to join the operator set + /// @param newMinimumWeight The new weight an operator must have to join the operator set function _updateMinimumWeight( - uint256 _newMinimumWeight + uint256 newMinimumWeight ) internal { uint256 oldMinimumWeight = _minimumWeight; - _minimumWeight = _newMinimumWeight; - emit MinimumWeightUpdated(oldMinimumWeight, _newMinimumWeight); + _minimumWeight = newMinimumWeight; + emit MinimumWeightUpdated(oldMinimumWeight, newMinimumWeight); } /// @notice Updates the quorum configuration - /// @dev Replaces the current quorum configuration with `_newQuorum` if valid. + /// @dev Replaces the current quorum configuration with `newQuorum` if valid. /// Reverts with `InvalidQuorum` if the new quorum configuration is not valid. /// Emits `QuorumUpdated` event with the old and new quorum configurations. - /// @param _newQuorum The new quorum configuration to set. + /// @param newQuorum The new quorum configuration to set. function _updateQuorumConfig( - Quorum memory _newQuorum + IECDSAStakeRegistryTypes.Quorum memory newQuorum ) internal { - if (!_isValidQuorum(_newQuorum)) { + if (!_isValidQuorum(newQuorum)) { revert InvalidQuorum(); } - Quorum memory oldQuorum = _quorum; + IECDSAStakeRegistryTypes.Quorum memory oldQuorum = _quorum; delete _quorum; - for (uint256 i; i < _newQuorum.strategies.length; i++) { - _quorum.strategies.push(_newQuorum.strategies[i]); + for (uint256 i; i < newQuorum.strategies.length; i++) { + _quorum.strategies.push(newQuorum.strategies[i]); } - emit QuorumUpdated(oldQuorum, _newQuorum); + emit QuorumUpdated(oldQuorum, newQuorum); } /// @dev Internal function to deregister an operator - /// @param _operator The operator's address to deregister + /// @param operator The operator's address to deregister function _deregisterOperator( - address _operator + address operator ) internal { - if (!_operatorRegistered[_operator]) { + if (!_operatorRegistered[operator]) { revert OperatorNotRegistered(); } _totalOperators--; - delete _operatorRegistered[_operator]; - int256 delta = _updateOperatorWeight(_operator); + delete _operatorRegistered[operator]; + int256 delta = _updateOperatorWeight(operator); _updateTotalWeight(delta); - IServiceManager(_serviceManager).deregisterOperatorFromAVS(_operator); - emit OperatorDeregistered(_operator, address(_serviceManager)); + IServiceManager(_serviceManager).deregisterOperatorFromAVS(operator); + emit OperatorDeregistered(operator, address(_serviceManager)); } /// @dev registers an operator through a provided signature - /// @param _operatorSignature Contains the operator's signature, salt, and expiry - /// @param _signingKey The signing key to add to the operator's history + /// @param operatorSignature Contains the operator's signature, salt, and expiry + /// @param signingKey The signing key to add to the operator's history function _registerOperatorWithSig( - address _operator, - ISignatureUtils.SignatureWithSaltAndExpiry memory _operatorSignature, - address _signingKey + address operator, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature, + address signingKey ) internal virtual { - if (_operatorRegistered[_operator]) { + if (_operatorRegistered[operator]) { revert OperatorAlreadyRegistered(); } _totalOperators++; - _operatorRegistered[_operator] = true; - int256 delta = _updateOperatorWeight(_operator); + _operatorRegistered[operator] = true; + int256 delta = _updateOperatorWeight(operator); _updateTotalWeight(delta); - _updateOperatorSigningKey(_operator, _signingKey); - IServiceManager(_serviceManager).registerOperatorToAVS(_operator, _operatorSignature); - emit OperatorRegistered(_operator, _serviceManager); + _updateOperatorSigningKey(operator, signingKey); + IServiceManager(_serviceManager).registerOperatorToAVS(operator, operatorSignature); + emit OperatorRegistered(operator, _serviceManager); } /// @dev Internal function to update an operator's signing key - /// @param _operator The address of the operator to update the signing key for - /// @param _newSigningKey The new signing key to set for the operator - function _updateOperatorSigningKey(address _operator, address _newSigningKey) internal { - address oldSigningKey = address(uint160(_operatorSigningKeyHistory[_operator].latest())); - if (_newSigningKey == oldSigningKey) { + /// @param operator The address of the operator to update the signing key for + /// @param newSigningKey The new signing key to set for the operator + function _updateOperatorSigningKey(address operator, address newSigningKey) internal { + address oldSigningKey = address(uint160(_operatorSigningKeyHistory[operator].latest())); + if (newSigningKey == oldSigningKey) { return; } - _operatorSigningKeyHistory[_operator].push(uint160(_newSigningKey)); - emit SigningKeyUpdate(_operator, block.number, _newSigningKey, oldSigningKey); + _operatorSigningKeyHistory[operator].push(uint160(newSigningKey)); + emit SigningKeyUpdate(operator, block.number, newSigningKey, oldSigningKey); } /// @notice Updates the weight of an operator and returns the previous and current weights. - /// @param _operator The address of the operator to update the weight of. + /// @param operator The address of the operator to update the weight of. function _updateOperatorWeight( - address _operator + address operator ) internal virtual returns (int256) { int256 delta; uint256 newWeight; - uint256 oldWeight = _operatorWeightHistory[_operator].latest(); - if (!_operatorRegistered[_operator]) { + uint256 oldWeight = _operatorWeightHistory[operator].latest(); + if (!_operatorRegistered[operator]) { delta -= int256(oldWeight); if (delta == 0) { return delta; } - _operatorWeightHistory[_operator].push(0); + _operatorWeightHistory[operator].push(0); } else { - newWeight = getOperatorWeight(_operator); + newWeight = getOperatorWeight(operator); delta = int256(newWeight) - int256(oldWeight); if (delta == 0) { return delta; } - _operatorWeightHistory[_operator].push(newWeight); + _operatorWeightHistory[operator].push(newWeight); } - emit OperatorWeightUpdated(_operator, oldWeight, newWeight); + emit OperatorWeightUpdated(operator, oldWeight, newWeight); return delta; } @@ -435,13 +386,13 @@ contract ECDSAStakeRegistry is * @dev Verifies that a specified quorum configuration is valid. A valid quorum has: * 1. Weights that sum to exactly 10,000 basis points, ensuring proportional representation. * 2. Unique strategies without duplicates to maintain quorum integrity. - * @param _quorum The quorum configuration to be validated. + * @param quorum The quorum configuration to be validated. * @return bool True if the quorum configuration is valid, otherwise false. */ function _isValidQuorum( - Quorum memory _quorum + IECDSAStakeRegistryTypes.Quorum memory quorum ) internal pure returns (bool) { - StrategyParams[] memory strategies = _quorum.strategies; + StrategyParams[] memory strategies = quorum.strategies; address lastStrategy; address currentStrategy; uint256 totalMultiplier; @@ -460,141 +411,141 @@ contract ECDSAStakeRegistry is /** * @notice Common logic to verify a batch of ECDSA signatures against a hash, using either last stake weight or at a specific block. - * @param _dataHash The hash of the data the signers endorsed. - * @param _operators A collection of addresses that endorsed the data hash. - * @param _signatures A collection of signatures matching the signers. - * @param _referenceBlock The block number for evaluating stake weight; use max uint32 for latest weight. + * @param digest The hash of the data the signers endorsed. + * @param operators A collection of addresses that endorsed the data hash. + * @param signatures A collection of signatures matching the signers. + * @param referenceBlock The block number for evaluating stake weight; use max uint32 for latest weight. */ function _checkSignatures( - bytes32 _dataHash, - address[] memory _operators, - bytes[] memory _signatures, - uint32 _referenceBlock + bytes32 digest, + address[] memory operators, + bytes[] memory signatures, + uint32 referenceBlock ) internal view { - uint256 signersLength = _operators.length; + uint256 signersLength = operators.length; address currentOperator; address lastOperator; address signer; uint256 signedWeight; - _validateSignaturesLength(signersLength, _signatures.length); + _validateSignaturesLength(signersLength, signatures.length); for (uint256 i; i < signersLength; i++) { - currentOperator = _operators[i]; - signer = _getOperatorSigningKey(currentOperator, _referenceBlock); + currentOperator = operators[i]; + signer = _getOperatorSigningKey(currentOperator, referenceBlock); _validateSortedSigners(lastOperator, currentOperator); - _validateSignature(signer, _dataHash, _signatures[i]); + _validateSignature(signer, digest, signatures[i]); lastOperator = currentOperator; - uint256 operatorWeight = _getOperatorWeight(currentOperator, _referenceBlock); + uint256 operatorWeight = _getOperatorWeight(currentOperator, referenceBlock); signedWeight += operatorWeight; } - _validateThresholdStake(signedWeight, _referenceBlock); + _validateThresholdStake(signedWeight, referenceBlock); } /// @notice Validates that the number of signers equals the number of signatures, and neither is zero. - /// @param _signersLength The number of signers. - /// @param _signaturesLength The number of signatures. + /// @param signersLength The number of signers. + /// @param signaturesLength The number of signatures. function _validateSignaturesLength( - uint256 _signersLength, - uint256 _signaturesLength + uint256 signersLength, + uint256 signaturesLength ) internal pure { - if (_signersLength != _signaturesLength) { + if (signersLength != signaturesLength) { revert LengthMismatch(); } - if (_signersLength == 0) { + if (signersLength == 0) { revert InvalidLength(); } } /// @notice Ensures that signers are sorted in ascending order by address. - /// @param _lastSigner The address of the last signer. - /// @param _currentSigner The address of the current signer. - function _validateSortedSigners(address _lastSigner, address _currentSigner) internal pure { - if (_lastSigner >= _currentSigner) { + /// @param lastSigner The address of the last signer. + /// @param currentSigner The address of the current signer. + function _validateSortedSigners(address lastSigner, address currentSigner) internal pure { + if (lastSigner >= currentSigner) { revert NotSorted(); } } /// @notice Validates a given signature against the signer's address and data hash. - /// @param _signer The address of the signer to validate. - /// @param _dataHash The hash of the data that is signed. - /// @param _signature The signature to validate. + /// @param signer The address of the signer to validate. + /// @param digest The hash of the data that is signed. + /// @param signature The signature to validate. function _validateSignature( - address _signer, - bytes32 _dataHash, - bytes memory _signature + address signer, + bytes32 digest, + bytes memory signature ) internal view { - if (!_signer.isValidSignatureNow(_dataHash, _signature)) { + if (!signer.isValidSignatureNow(digest, signature)) { revert InvalidSignature(); } } /// @notice Retrieves the operator weight for a signer, either at the last checkpoint or a specified block. - /// @param _operator The operator to query their signing key history for - /// @param _referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint. + /// @param operator The operator to query their signing key history for + /// @param referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint. /// @return The weight of the operator. function _getOperatorSigningKey( - address _operator, - uint32 _referenceBlock + address operator, + uint32 referenceBlock ) internal view returns (address) { - if (_referenceBlock >= block.number) { + if (referenceBlock >= block.number) { revert InvalidReferenceBlock(); } - return address(uint160(_operatorSigningKeyHistory[_operator].getAtBlock(_referenceBlock))); + return address(uint160(_operatorSigningKeyHistory[operator].getAtBlock(referenceBlock))); } /// @notice Retrieves the operator weight for a signer, either at the last checkpoint or a specified block. - /// @param _signer The address of the signer whose weight is returned. - /// @param _referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint. + /// @param signer The address of the signer whose weight is returned. + /// @param referenceBlock The block number to query the operator's weight at, or the maximum uint32 value for the last checkpoint. /// @return The weight of the operator. function _getOperatorWeight( - address _signer, - uint32 _referenceBlock + address signer, + uint32 referenceBlock ) internal view returns (uint256) { - if (_referenceBlock >= block.number) { + if (referenceBlock >= block.number) { revert InvalidReferenceBlock(); } - return _operatorWeightHistory[_signer].getAtBlock(_referenceBlock); + return _operatorWeightHistory[signer].getAtBlock(referenceBlock); } /// @notice Retrieve the total stake weight at a specific block or the latest if not specified. - /// @dev If the `_referenceBlock` is the maximum value for uint32, the latest total weight is returned. - /// @param _referenceBlock The block number to retrieve the total stake weight from. + /// @dev If the `referenceBlock` is the maximum value for uint32, the latest total weight is returned. + /// @param referenceBlock The block number to retrieve the total stake weight from. /// @return The total stake weight at the given block or the latest if the given block is the max uint32 value. function _getTotalWeight( - uint32 _referenceBlock + uint32 referenceBlock ) internal view returns (uint256) { - if (_referenceBlock >= block.number) { + if (referenceBlock >= block.number) { revert InvalidReferenceBlock(); } - return _totalWeightHistory.getAtBlock(_referenceBlock); + return _totalWeightHistory.getAtBlock(referenceBlock); } /// @notice Retrieves the threshold stake for a given reference block. - /// @param _referenceBlock The block number to query the threshold stake for. + /// @param referenceBlock The block number to query the threshold stake for. /// If set to the maximum uint32 value, it retrieves the latest threshold stake. /// @return The threshold stake in basis points for the reference block. function _getThresholdStake( - uint32 _referenceBlock + uint32 referenceBlock ) internal view returns (uint256) { - if (_referenceBlock >= block.number) { + if (referenceBlock >= block.number) { revert InvalidReferenceBlock(); } - return _thresholdWeightHistory.getAtBlock(_referenceBlock); + return _thresholdWeightHistory.getAtBlock(referenceBlock); } /// @notice Validates that the cumulative stake of signed messages meets or exceeds the required threshold. - /// @param _signedWeight The cumulative weight of the signers that have signed the message. - /// @param _referenceBlock The block number to verify the stake threshold for - function _validateThresholdStake(uint256 _signedWeight, uint32 _referenceBlock) internal view { - uint256 totalWeight = _getTotalWeight(_referenceBlock); - if (_signedWeight > totalWeight) { + /// @param signedWeight The cumulative weight of the signers that have signed the message. + /// @param referenceBlock The block number to verify the stake threshold for + function _validateThresholdStake(uint256 signedWeight, uint32 referenceBlock) internal view { + uint256 totalWeight = _getTotalWeight(referenceBlock); + if (signedWeight > totalWeight) { revert InvalidSignedWeight(); } - uint256 thresholdStake = _getThresholdStake(_referenceBlock); - if (thresholdStake > _signedWeight) { + uint256 thresholdStake = _getThresholdStake(referenceBlock); + if (thresholdStake > signedWeight) { revert InsufficientSignedStake(); } } diff --git a/src/unaudited/ECDSAStakeRegistryStorage.sol b/src/unaudited/ECDSAStakeRegistryStorage.sol index a47701e3..0d94844a 100644 --- a/src/unaudited/ECDSAStakeRegistryStorage.sol +++ b/src/unaudited/ECDSAStakeRegistryStorage.sol @@ -6,12 +6,10 @@ import {IDelegationManager} from import {CheckpointsUpgradeable} from "@openzeppelin-upgrades/contracts/utils/CheckpointsUpgradeable.sol"; import { - ECDSAStakeRegistryEventsAndErrors, - Quorum, - StrategyParams -} from "../interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; + IECDSAStakeRegistry, IECDSAStakeRegistryTypes +} from "../interfaces/IECDSAStakeRegistry.sol"; -abstract contract ECDSAStakeRegistryStorage is ECDSAStakeRegistryEventsAndErrors { +abstract contract ECDSAStakeRegistryStorage is IECDSAStakeRegistry { /// @notice Manages staking delegations through the DelegationManager interface IDelegationManager internal immutable DELEGATION_MANAGER; @@ -22,7 +20,7 @@ abstract contract ECDSAStakeRegistryStorage is ECDSAStakeRegistryEventsAndErrors uint256 internal _totalOperators; /// @notice Stores the current quorum configuration - Quorum internal _quorum; + IECDSAStakeRegistryTypes.Quorum internal _quorum; /// @notice Specifies the weight required to become an operator uint256 internal _minimumWeight; diff --git a/test/ffi/BLSPubKeyCompendiumFFI.t.sol b/test/ffi/BLSPubKeyCompendiumFFI.t.sol index b2c078b2..fd1902cf 100644 --- a/test/ffi/BLSPubKeyCompendiumFFI.t.sol +++ b/test/ffi/BLSPubKeyCompendiumFFI.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.27; import "../../src/BLSApkRegistry.sol"; import "../ffi/util/G2Operations.sol"; -import {IBLSApkRegistry} from "../../src/interfaces/IBLSApkRegistry.sol"; +import {IBLSApkRegistry, IBLSApkRegistryTypes} from "../../src/interfaces/IBLSApkRegistry.sol"; contract BLSApkRegistryFFITests is G2Operations { using BN254 for BN254.G1Point; @@ -15,7 +15,7 @@ contract BLSApkRegistryFFITests is G2Operations { IRegistryCoordinator registryCoordinator; uint256 privKey; - IBLSApkRegistry.PubkeyRegistrationParams pubkeyRegistrationParams; + IBLSApkRegistryTypes.PubkeyRegistrationParams pubkeyRegistrationParams; address alice = address(0x69); diff --git a/test/ffi/UpdateOperators.t.sol b/test/ffi/UpdateOperators.t.sol index b7bba5b0..349bb8d1 100644 --- a/test/ffi/UpdateOperators.t.sol +++ b/test/ffi/UpdateOperators.t.sol @@ -1027,7 +1027,7 @@ contract Integration_AVS_Sync_GasCosts_FFI is IntegrationChecks { // READ JSON CONFIG DATA string memory config_data = vm.readFile(keysConfigPath); for (uint256 i = 0; i < MAX_OPERATOR_COUNT; i++) { - IBLSApkRegistry.PubkeyRegistrationParams memory pubkey; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory pubkey; uint256 privateKey = privateKeys[i]; // G1 pubkey.pubkeyG1.X = @@ -1050,7 +1050,7 @@ contract Integration_AVS_Sync_GasCosts_FFI is IntegrationChecks { function _generateOperatorKeys() internal { for (uint256 i = 0; i < 200; i++) { - IBLSApkRegistry.PubkeyRegistrationParams memory pubkey; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory pubkey; uint256 privateKey = privateKeys[i]; pubkey.pubkeyG1 = BN254.generatorG1().scalar_mul(privateKey); pubkey.pubkeyG2 = G2Operations.mul(privateKey); diff --git a/test/integration/IntegrationBase.t.sol b/test/integration/IntegrationBase.t.sol index 15371667..13c8741d 100644 --- a/test/integration/IntegrationBase.t.sol +++ b/test/integration/IntegrationBase.t.sol @@ -29,24 +29,24 @@ abstract contract IntegrationBase is IntegrationConfig { /// @dev Also checks that the user has NEVER_REGISTERED status function assert_HasNoOperatorInfo(User user, string memory err) internal { - IRegistryCoordinator.OperatorInfo memory info = _getOperatorInfo(user); + IRegistryCoordinatorTypes.OperatorInfo memory info = _getOperatorInfo(user); assertEq(info.operatorId, bytes32(0), err); - assertTrue(info.status == IRegistryCoordinator.OperatorStatus.NEVER_REGISTERED, err); + assertTrue(info.status == IRegistryCoordinatorTypes.OperatorStatus.NEVER_REGISTERED, err); } function assert_HasRegisteredStatus(User user, string memory err) internal { - IRegistryCoordinator.OperatorStatus status = + IRegistryCoordinatorTypes.OperatorStatus status = registryCoordinator.getOperatorStatus(address(user)); - assertTrue(status == IRegistryCoordinator.OperatorStatus.REGISTERED, err); + assertTrue(status == IRegistryCoordinatorTypes.OperatorStatus.REGISTERED, err); } function assert_HasDeregisteredStatus(User user, string memory err) internal { - IRegistryCoordinator.OperatorStatus status = + IRegistryCoordinatorTypes.OperatorStatus status = registryCoordinator.getOperatorStatus(address(user)); - assertTrue(status == IRegistryCoordinator.OperatorStatus.DEREGISTERED, err); + assertTrue(status == IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED, err); } function assert_EmptyQuorumBitmap(User user, string memory err) internal { @@ -243,8 +243,8 @@ abstract contract IntegrationBase is IntegrationConfig { } function assert_Snap_Unchanged_OperatorInfo(User user, string memory err) internal { - IRegistryCoordinator.OperatorInfo memory curInfo = _getOperatorInfo(user); - IRegistryCoordinator.OperatorInfo memory prevInfo = _getPrevOperatorInfo(user); + IRegistryCoordinatorTypes.OperatorInfo memory curInfo = _getOperatorInfo(user); + IRegistryCoordinatorTypes.OperatorInfo memory prevInfo = _getPrevOperatorInfo(user); assertEq(prevInfo.operatorId, curInfo.operatorId, err); assertTrue(prevInfo.status == curInfo.status, err); @@ -866,13 +866,13 @@ abstract contract IntegrationBase is IntegrationConfig { function _getOperatorInfo( User user - ) internal view returns (IRegistryCoordinator.OperatorInfo memory) { + ) internal view returns (IRegistryCoordinatorTypes.OperatorInfo memory) { return registryCoordinator.getOperator(address(user)); } function _getPrevOperatorInfo( User user - ) internal timewarp returns (IRegistryCoordinator.OperatorInfo memory) { + ) internal timewarp returns (IRegistryCoordinatorTypes.OperatorInfo memory) { return _getOperatorInfo(user); } diff --git a/test/integration/IntegrationConfig.t.sol b/test/integration/IntegrationConfig.t.sol index e04a7204..a55fc85d 100644 --- a/test/integration/IntegrationConfig.t.sol +++ b/test/integration/IntegrationConfig.t.sol @@ -8,7 +8,7 @@ import "test/ffi/util/G2Operations.sol"; import "test/integration/utils/BitmapStrings.t.sol"; contract Constants { - /// Quorum Config: + /// IECDSAStakeRegistryTypes.Quorum Config: /// @dev Default OperatorSetParam values used to initialize quorums /// NOTE: This means each quorum has an operator limit of MAX_OPERATOR_COUNT by default @@ -73,7 +73,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { /// (See _fetchKeypair) uint256 fetchIdx = 0; uint256[] privKeys; - IBLSApkRegistry.PubkeyRegistrationParams[] pubkeys; + IBLSApkRegistryTypes.PubkeyRegistrationParams[] pubkeys; /// @dev Current initialized quorums are tracked here: uint256 quorumCount; @@ -93,7 +93,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { */ constructor() { for (uint256 i = 0; i < NUM_GENERATED_OPERATORS; i++) { - IBLSApkRegistry.PubkeyRegistrationParams memory pubkey; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory pubkey; uint256 privKey = uint256(keccak256(abi.encodePacked(i + 1))); pubkey.pubkeyG1 = BN254.generatorG1().scalar_mul(privKey); @@ -158,7 +158,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { emit log_named_uint("_configRand: number of quorums being initialized", quorumCount); // Default OperatorSetParams for all quorums - IRegistryCoordinator.OperatorSetParam memory operatorSet = IRegistryCoordinator + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSet = IRegistryCoordinatorTypes .OperatorSetParam({ maxOperatorCount: MAX_OPERATOR_COUNT, kickBIPsOfOperatorStake: KICK_BIPS_OPERATOR_STAKE, @@ -167,7 +167,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { // Initialize each quorum for (uint256 i = 0; i < quorumCount; i++) { - IStakeRegistry.StrategyParams[] memory strategyParams = _randStrategyParams(); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = _randStrategyParams(); uint96 minimumStake = _randMinStake(); emit log_named_uint("_configRand: creating quorum", i); @@ -233,7 +233,8 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { string memory name ) internal returns (User, IStrategy[] memory, uint256[] memory) { // Create User contract and give it a unique BLS keypair - (uint256 privKey, IBLSApkRegistry.PubkeyRegistrationParams memory pubkey) = _fetchKeypair(); + (uint256 privKey, IBLSApkRegistryTypes.PubkeyRegistrationParams memory pubkey) = + _fetchKeypair(); // Use userFlags to pick the kind of user to generate User user; @@ -422,7 +423,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { function _fetchKeypair() internal - returns (uint256, IBLSApkRegistry.PubkeyRegistrationParams memory) + returns (uint256, IBLSApkRegistryTypes.PubkeyRegistrationParams memory) { // should probably just generate another keypair at this point if (fetchIdx == privKeys.length) { @@ -432,7 +433,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { } uint256 privKey = privKeys[fetchIdx]; - IBLSApkRegistry.PubkeyRegistrationParams memory pubkey = pubkeys[fetchIdx]; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory pubkey = pubkeys[fetchIdx]; fetchIdx++; return (privKey, pubkey); @@ -528,7 +529,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { /// NOTE: This should only be used when creating a quorum for the first time. If you're /// selecting strategies to add after the quorum has been initialized, this is likely to /// return duplicates. - function _randStrategyParams() private returns (IStakeRegistry.StrategyParams[] memory) { + function _randStrategyParams() private returns (IStakeRegistryTypes.StrategyParams[] memory) { uint256 strategyFlag = _randValue(numStrategyFlags); uint256 strategyCount; @@ -548,11 +549,11 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { revert("_randStrategyCount: flag not recognized"); } - IStakeRegistry.StrategyParams[] memory params = - new IStakeRegistry.StrategyParams[](strategyCount); + IStakeRegistryTypes.StrategyParams[] memory params = + new IStakeRegistryTypes.StrategyParams[](strategyCount); for (uint256 i = 0; i < params.length; i++) { - params[i] = IStakeRegistry.StrategyParams({ + params[i] = IStakeRegistryTypes.StrategyParams({ strategy: allStrats[i], multiplier: DEFAULT_STRATEGY_MULTIPLIER }); diff --git a/test/integration/IntegrationDeployer.t.sol b/test/integration/IntegrationDeployer.t.sol index 5d5ffadd..66404ff7 100644 --- a/test/integration/IntegrationDeployer.t.sol +++ b/test/integration/IntegrationDeployer.t.sol @@ -383,7 +383,8 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { rewardsInitiator: address(msg.sender) }); - StakeType[] memory quorumStakeTypes = new StakeType[](0); + IStakeRegistryTypes.StakeType[] memory quorumStakeTypes = + new IStakeRegistryTypes.StakeType[](0); uint32[] memory slashableStakeQuorumLookAheadPeriods = new uint32[](0); RegistryCoordinator registryCoordinatorImplementation = new RegistryCoordinator( @@ -405,7 +406,7 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { 0, /*initialPausedStatus*/ new IRegistryCoordinator.OperatorSetParam[](0), new uint96[](0), - new IStakeRegistry.StrategyParams[][](0), + new IStakeRegistryTypes.StrategyParams[][](0), quorumStakeTypes, slashableStakeQuorumLookAheadPeriods ) diff --git a/test/integration/User.t.sol b/test/integration/User.t.sol index fbc491f5..9bd80c5b 100644 --- a/test/integration/User.t.sol +++ b/test/integration/User.t.sol @@ -16,6 +16,7 @@ import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; import "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; // Middleware +import "src/interfaces/IRegistryCoordinator.sol"; import "src/RegistryCoordinator.sol"; import "src/BLSApkRegistry.sol"; import "src/IndexRegistry.sol"; @@ -66,7 +67,7 @@ contract User is Test { // BLS keypair: uint256 privKey; - IBLSApkRegistry.PubkeyRegistrationParams pubkeyParams; + IBLSApkRegistryTypes.PubkeyRegistrationParams pubkeyParams; // EIP1271 sigs: mapping(bytes32 => bool) digests; @@ -75,7 +76,7 @@ contract User is Test { constructor( string memory name, uint256 _privKey, - IBLSApkRegistry.PubkeyRegistrationParams memory _pubkeyParams + IBLSApkRegistryTypes.PubkeyRegistrationParams memory _pubkeyParams ) { IUserDeployer deployer = IUserDeployer(msg.sender); @@ -169,20 +170,24 @@ contract User is Test { uint256 stdIdx; while (churnIdx + stdIdx < allQuorums.length) { if (churnIdx == churnQuorums.length) { - kickParams[churnIdx + stdIdx] = - IRegistryCoordinator.OperatorKickParam({quorumNumber: 0, operator: address(0)}); + kickParams[churnIdx + stdIdx] = IRegistryCoordinatorTypes.OperatorKickParam({ + quorumNumber: 0, + operator: address(0) + }); stdIdx++; } else if ( stdIdx == standardQuorums.length || churnQuorums[churnIdx] < standardQuorums[stdIdx] ) { - kickParams[churnIdx + stdIdx] = IRegistryCoordinator.OperatorKickParam({ + kickParams[churnIdx + stdIdx] = IRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: uint8(churnQuorums[churnIdx]), operator: address(churnTargets[churnIdx]) }); churnIdx++; } else if (standardQuorums[stdIdx] < churnQuorums[churnIdx]) { - kickParams[churnIdx + stdIdx] = - IRegistryCoordinator.OperatorKickParam({quorumNumber: 0, operator: address(0)}); + kickParams[churnIdx + stdIdx] = IRegistryCoordinatorTypes.OperatorKickParam({ + quorumNumber: 0, + operator: address(0) + }); stdIdx++; } else { revert("User.registerOperatorWithChurn: malformed input"); @@ -384,7 +389,7 @@ contract User_AltMethods is User { constructor( string memory name, uint256 _privKey, - IBLSApkRegistry.PubkeyRegistrationParams memory _pubkeyParams + IBLSApkRegistryTypes.PubkeyRegistrationParams memory _pubkeyParams ) User(name, _privKey, _pubkeyParams) {} /// @dev Rather than calling deregisterOperator, this pranks the ejector and calls diff --git a/test/mocks/RegistryCoordinatorMock.sol b/test/mocks/RegistryCoordinatorMock.sol index d0464db2..1c8d4aee 100644 --- a/test/mocks/RegistryCoordinatorMock.sol +++ b/test/mocks/RegistryCoordinatorMock.sol @@ -2,109 +2,167 @@ pragma solidity ^0.8.27; import "../../src/interfaces/IRegistryCoordinator.sol"; - -contract RegistryCoordinatorMock is IRegistryCoordinator { - function blsApkRegistry() external view returns (IBLSApkRegistry) {} - - function ejectOperator(address operator, bytes calldata quorumNumbers) external {} - +import "../../src/libraries/BN254.sol"; + +abstract contract RegistryCoordinatorMock is IRegistryCoordinator { + // Add missing function declarations from interface + function OPERATOR_CHURN_APPROVAL_TYPEHASH() external pure virtual returns (bytes32); + function PUBKEY_REGISTRATION_TYPEHASH() external pure virtual returns (bytes32); + function allocationManager() external view virtual returns (IAllocationManager); + function calculateOperatorChurnApprovalDigestHash( + address registeringOperator, + bytes32 registeringOperatorId, + OperatorKickParam[] memory operatorKickParams, + bytes32 salt, + uint256 expiry + ) external view virtual returns (bytes32); + function churnApprover() external view virtual returns (address); + function createSlashableStakeQuorum( + OperatorSetParam memory operatorSetParams, + uint96 minimumStake, + IStakeRegistryTypes.StrategyParams[] memory strategyParams, + uint32 lookAheadPeriod + ) external virtual; + function createTotalDelegatedStakeQuorum( + OperatorSetParam memory operatorSetParams, + uint96 minimumStake, + IStakeRegistryTypes.StrategyParams[] memory strategyParams + ) external virtual; + function deregisterOperator( + address operator, + uint32[] memory operatorSetIds + ) external virtual; + function ejectionCooldown() external view virtual returns (uint256); + function ejector() external view virtual returns (address); + function enableOperatorSets() external virtual; + function initialize( + address _initialOwner, + address _churnApprover, + address _ejector, + uint256 _initialPausedStatus, + OperatorSetParam[] memory _operatorSetParams, + uint96[] memory _minimumStakes, + IStakeRegistryTypes.StrategyParams[][] memory _strategyParams, + IStakeRegistryTypes.StakeType[] memory _stakeTypes, + uint32[] memory _lookAheadPeriods + ) external virtual; + function isChurnApproverSaltUsed( + bytes32 salt + ) external view virtual returns (bool); + function isUsingOperatorSets() external view virtual returns (bool); + function lastEjectionTimestamp( + address operator + ) external view virtual returns (uint256); + function registerOperator( + address operator, + uint32[] memory operatorSetIds, + bytes memory data + ) external virtual; + function registerOperator( + bytes memory quorumNumbers, + string memory socket, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external virtual; + function registerOperatorWithChurn( + bytes calldata quorumNumbers, + string memory socket, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, + OperatorKickParam[] memory operatorKickParams, + ISignatureUtils.SignatureWithSaltAndExpiry memory churnApproverSignature, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external virtual; + function setChurnApprover( + address _churnApprover + ) external virtual; + function setEjectionCooldown( + uint256 _ejectionCooldown + ) external virtual; + function setEjector( + address _ejector + ) external virtual; + function setOperatorSetParams( + uint8 quorumNumber, + OperatorSetParam memory operatorSetParams + ) external virtual; + function updateOperators( + address[] memory operators + ) external virtual; + function updateOperatorsForQuorum( + address[][] memory operatorsPerQuorum, + bytes calldata quorumNumbers + ) external virtual; + function updateSocket( + string memory socket + ) external virtual; + + // Keep existing implementations + function blsApkRegistry() external view virtual returns (IBLSApkRegistry) {} + function ejectOperator(address operator, bytes calldata quorumNumbers) external virtual {} function getOperatorSetParams( uint8 quorumNumber - ) external view returns (OperatorSetParam memory) {} - - function indexRegistry() external view returns (IIndexRegistry) {} - - function stakeRegistry() external view returns (IStakeRegistry) {} - - function quorumCount() external view returns (uint8) {} - /// @notice Returns the bitmap of the quorums the operator is registered for. - function operatorIdToQuorumBitmap( - bytes32 pubkeyHash - ) external view returns (uint256) {} - + ) external view virtual returns (OperatorSetParam memory) {} + function indexRegistry() external view virtual returns (IIndexRegistry) {} + function stakeRegistry() external view virtual returns (IStakeRegistry) {} + function quorumCount() external view virtual returns (uint8) {} function getOperator( address operator - ) external view returns (OperatorInfo memory) {} - - /// @notice Returns the stored id for the specified `operator`. + ) external view virtual returns (OperatorInfo memory) {} function getOperatorId( address operator - ) external view returns (bytes32) {} - - /// @notice Returns the operator address for the given `operatorId` + ) external view virtual returns (bytes32) {} function getOperatorFromId( bytes32 operatorId - ) external view returns (address) {} - - /// @notice Returns the status for the given `operator` + ) external view virtual returns (address) {} function getOperatorStatus( address operator - ) external view returns (IRegistryCoordinator.OperatorStatus) {} - - /// @notice Returns task number from when `operator` has been registered. - function getFromTaskNumberForOperator( - address operator - ) external view returns (uint32) {} - + ) external view virtual returns (OperatorStatus) {} function getQuorumBitmapIndicesAtBlockNumber( uint32 blockNumber, bytes32[] memory operatorIds - ) external view returns (uint32[] memory) {} - - /// @notice Returns the quorum bitmap for the given `operatorId` at the given `blockNumber` via the `index` + ) external view virtual returns (uint32[] memory) {} function getQuorumBitmapAtBlockNumberByIndex( bytes32 operatorId, uint32 blockNumber, uint256 index - ) external view returns (uint192) {} - - /// @notice Returns the `index`th entry in the operator with `operatorId`'s bitmap history + ) external view virtual returns (uint192) {} function getQuorumBitmapUpdateByIndex( bytes32 operatorId, uint256 index - ) external view returns (QuorumBitmapUpdate memory) {} - - /// @notice Returns the current quorum bitmap for the given `operatorId` + ) external view virtual returns (QuorumBitmapUpdate memory) {} function getCurrentQuorumBitmap( bytes32 operatorId - ) external view returns (uint192) {} - - /// @notice Returns the length of the quorum bitmap history for the given `operatorId` + ) external view virtual returns (uint192) {} function getQuorumBitmapHistoryLength( bytes32 operatorId - ) external view returns (uint256) {} - - function numRegistries() external view returns (uint256) {} - + ) external view virtual returns (uint256) {} + function numRegistries() external view virtual returns (uint256) {} function registries( uint256 - ) external view returns (address) {} - - function registerOperator(bytes memory quorumNumbers, bytes calldata) external {} - - function deregisterOperator(bytes calldata quorumNumbers, bytes calldata) external {} + ) external view virtual returns (address) {} + function deregisterOperator( + bytes calldata quorumNumbers + ) external virtual {} function pubkeyRegistrationMessageHash( address operator - ) public view returns (BN254.G1Point memory) { + ) public view virtual returns (BN254.G1Point memory) { return BN254.hashToG1(keccak256(abi.encode(operator))); } function quorumUpdateBlockNumber( uint8 quorumNumber - ) external view returns (uint256) {} - - function owner() external view returns (address) {} - - function serviceManager() external view returns (IServiceManager) {} + ) external view virtual returns (uint256) {} + function owner() external view virtual returns (address) {} + function serviceManager() external view virtual returns (IServiceManager) {} function isM2Quorum( uint8 quorumNumber - ) external view returns (bool) { + ) external view virtual returns (bool) { return false; } - function isOperatorSetAVS() external view returns (bool) { + function isOperatorSetAVS() external view virtual returns (bool) { return false; } } diff --git a/test/mocks/StakeRegistryMock.sol b/test/mocks/StakeRegistryMock.sol index a70c8f13..f428928e 100644 --- a/test/mocks/StakeRegistryMock.sol +++ b/test/mocks/StakeRegistryMock.sol @@ -12,6 +12,19 @@ contract StakeRegistryMock is IStakeRegistry { // bitmap returned by the mocked `updateOperatorStake` function uint192 updateOperatorStakeReturnBitmap; + function isOperatorSetQuorum( + uint8 quorumNumber + ) external view returns (bool) {} + + function getStakeHistoryLength( + bytes32 operatorId, + uint8 quorumNumber + ) external view returns (uint256) {} + + function setMinimumStakeForQuorum(uint8 quorumNumber, uint96 minimumStake) external {} + + function setSlashableStakeLookahead(uint8 quorumNumber, uint32 lookAheadBlocks) external {} + function set_updateOperatorStakeReturnBitmap( uint192 newValue ) external { diff --git a/test/unit/BLSSignatureCheckerUnit.t.sol b/test/unit/BLSSignatureCheckerUnit.t.sol index a58d6112..37a1115f 100644 --- a/test/unit/BLSSignatureCheckerUnit.t.sol +++ b/test/unit/BLSSignatureCheckerUnit.t.sol @@ -3,7 +3,10 @@ pragma solidity ^0.8.27; import "../../src/BLSSignatureChecker.sol"; import "../utils/BLSMockAVSDeployer.sol"; -import {IBLSSignatureCheckerErrors} from "../../src/interfaces/IBLSSignatureChecker.sol"; +import { + IBLSSignatureCheckerErrors, + IBLSSignatureCheckerTypes +} from "../../src/interfaces/IBLSSignatureChecker.sol"; import {IBLSApkRegistryErrors} from "../../src/interfaces/IBLSApkRegistry.sol"; import {QuorumBitmapHistoryLib} from "../../src/libraries/QuorumBitmapHistoryLib.sol"; import {IStakeRegistryErrors} from "../../src/interfaces/IStakeRegistry.sol"; @@ -201,8 +204,8 @@ contract BLSSignatureCheckerUnitTests is BLSMockAVSDeployer { 1, numNonSigners, quorumBitmap ); - IBLSSignatureChecker.NonSignerStakesAndSignature memory incorrectLengthInputs = - IBLSSignatureChecker.NonSignerStakesAndSignature({ + IBLSSignatureCheckerTypes.NonSignerStakesAndSignature memory incorrectLengthInputs = + IBLSSignatureCheckerTypes.NonSignerStakesAndSignature({ nonSignerQuorumBitmapIndices: nonSignerStakesAndSignature.nonSignerQuorumBitmapIndices, nonSignerPubkeys: nonSignerStakesAndSignature.nonSignerPubkeys, quorumApks: nonSignerStakesAndSignature.quorumApks, diff --git a/test/unit/ECDSAServiceManager.t.sol b/test/unit/ECDSAServiceManager.t.sol index bcd17052..aac2bd38 100644 --- a/test/unit/ECDSAServiceManager.t.sol +++ b/test/unit/ECDSAServiceManager.t.sol @@ -10,7 +10,7 @@ // import {ECDSAServiceManagerMock} from "../mocks/ECDSAServiceManagerMock.sol"; // import {ECDSAStakeRegistryMock} from "../mocks/ECDSAStakeRegistryMock.sol"; -// import {Quorum, StrategyParams} from "../../src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; +// import {IECDSAStakeRegistryTypes.Quorum, StrategyParams} from "../../src/interfaces/IECDSAStakeRegistry.sol"; // contract MockDelegationManager { // function operatorShares(address, address) external pure returns (uint256) { @@ -84,7 +84,7 @@ // operator2 = vm.addr(operator2Pk); // // Create a quorum -// Quorum memory quorum = Quorum({strategies: new StrategyParams[](2)}); +// IECDSAStakeRegistryTypes.Quorum memory quorum = IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](2)}); // quorum.strategies[0] = StrategyParams({ // strategy: IStrategy(address(420)), // multiplier: 5000 diff --git a/test/unit/ECDSAStakeRegistryEqualWeightUnit.t.sol b/test/unit/ECDSAStakeRegistryEqualWeightUnit.t.sol index 2878e67d..59f4497f 100644 --- a/test/unit/ECDSAStakeRegistryEqualWeightUnit.t.sol +++ b/test/unit/ECDSAStakeRegistryEqualWeightUnit.t.sol @@ -7,10 +7,9 @@ import {IDelegationManager} from import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import { - ECDSAStakeRegistryEventsAndErrors, - Quorum, - StrategyParams -} from "../../src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; + IECDSAStakeRegistry, + IECDSAStakeRegistryTypes +} from "../../src/interfaces/IECDSAStakeRegistry.sol"; import {ECDSAStakeRegistrySetup} from "./ECDSAStakeRegistryUnit.t.sol"; import {ECDSAStakeRegistryEqualWeight} from "../../src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol"; @@ -23,7 +22,8 @@ contract EqualWeightECDSARegistry is ECDSAStakeRegistrySetup { fixedWeightRegistry = new ECDSAStakeRegistryEqualWeight(IDelegationManager(address(mockDelegationManager))); IStrategy mockStrategy = IStrategy(address(0x1234)); - Quorum memory quorum = Quorum({strategies: new StrategyParams[](1)}); + IECDSAStakeRegistryTypes.Quorum memory quorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](1)}); quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10_000}); fixedWeightRegistry.initialize(address(mockServiceManager), 100, quorum); diff --git a/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol b/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol index ced14a41..033e5242 100644 --- a/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol +++ b/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol @@ -7,10 +7,10 @@ import {IDelegationManager} from import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import { - ECDSAStakeRegistryEventsAndErrors, - Quorum, - StrategyParams -} from "../../src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; + IECDSAStakeRegistry, + IECDSAStakeRegistryTypes, + IECDSAStakeRegistryErrors +} from "../../src/interfaces/IECDSAStakeRegistry.sol"; import {ECDSAStakeRegistrySetup} from "./ECDSAStakeRegistryUnit.t.sol"; import {ECDSAStakeRegistryPermissioned} from "../../src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol"; @@ -23,7 +23,8 @@ contract PermissionedECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { permissionedRegistry = new ECDSAStakeRegistryPermissioned(IDelegationManager(address(mockDelegationManager))); IStrategy mockStrategy = IStrategy(address(0x1234)); - Quorum memory quorum = Quorum({strategies: new StrategyParams[](1)}); + IECDSAStakeRegistryTypes.Quorum memory quorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](1)}); quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10_000}); permissionedRegistry.initialize(address(mockServiceManager), 100, quorum); @@ -75,7 +76,9 @@ contract PermissionedECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { function test_RevertsWhen_NotOperator_EjectOperator() public { address notOperator = address(0xBEEF); - vm.expectRevert(abi.encodeWithSelector(OperatorNotRegistered.selector)); + vm.expectRevert( + abi.encodeWithSelector(IECDSAStakeRegistryErrors.OperatorNotRegistered.selector) + ); permissionedRegistry.ejectOperator(notOperator); } diff --git a/test/unit/ECDSAStakeRegistryUnit.t.sol b/test/unit/ECDSAStakeRegistryUnit.t.sol index 89a4dc98..0416b4cd 100644 --- a/test/unit/ECDSAStakeRegistryUnit.t.sol +++ b/test/unit/ECDSAStakeRegistryUnit.t.sol @@ -10,10 +10,11 @@ import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy import {ECDSAStakeRegistry} from "../../src/unaudited/ECDSAStakeRegistry.sol"; import { - ECDSAStakeRegistryEventsAndErrors, - Quorum, - StrategyParams -} from "../../src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol"; + IECDSAStakeRegistry, + IECDSAStakeRegistryErrors, + IECDSAStakeRegistryTypes, + IECDSAStakeRegistryEvents +} from "../../src/interfaces/IECDSAStakeRegistry.sol"; contract MockServiceManager { // solhint-disable-next-line @@ -44,7 +45,7 @@ contract MockDelegationManager { } } -contract ECDSAStakeRegistrySetup is Test, ECDSAStakeRegistryEventsAndErrors { +contract ECDSAStakeRegistrySetup is Test, IECDSAStakeRegistryEvents { MockDelegationManager public mockDelegationManager; MockServiceManager public mockServiceManager; ECDSAStakeRegistry public registry; @@ -64,8 +65,11 @@ contract ECDSAStakeRegistrySetup is Test, ECDSAStakeRegistryEventsAndErrors { mockDelegationManager = new MockDelegationManager(); mockServiceManager = new MockServiceManager(); IStrategy mockStrategy = IStrategy(address(0x1234)); - Quorum memory quorum = Quorum({strategies: new StrategyParams[](1)}); - quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10_000}); + IECDSAStakeRegistryTypes.Quorum memory quorum = IECDSAStakeRegistryTypes.Quorum({ + strategies: new IECDSAStakeRegistryTypes.StrategyParams[](1) + }); + quorum.strategies[0] = + IECDSAStakeRegistryTypes.StrategyParams({strategy: mockStrategy, multiplier: 10_000}); registry = new ECDSAStakeRegistry(IDelegationManager(address(mockDelegationManager))); registry.initialize(address(mockServiceManager), 100, quorum); ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature; @@ -81,9 +85,12 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { function test_UpdateQuorumConfig() public { IStrategy mockStrategy = IStrategy(address(420)); - Quorum memory oldQuorum = registry.quorum(); - Quorum memory newQuorum = Quorum({strategies: new StrategyParams[](1)}); - newQuorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10_000}); + IECDSAStakeRegistryTypes.Quorum memory oldQuorum = registry.quorum(); + IECDSAStakeRegistryTypes.Quorum memory newQuorum = IECDSAStakeRegistryTypes.Quorum({ + strategies: new IECDSAStakeRegistryTypes.StrategyParams[](1) + }); + newQuorum.strategies[0] = + IECDSAStakeRegistryTypes.StrategyParams({strategy: mockStrategy, multiplier: 10_000}); address[] memory operators = new address[](2); operators[0] = operator1; operators[1] = operator2; @@ -95,8 +102,10 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { } function test_RevertsWhen_InvalidQuorum_UpdateQuourmConfig() public { - Quorum memory invalidQuorum = Quorum({strategies: new StrategyParams[](1)}); - invalidQuorum.strategies[0] = StrategyParams({ + IECDSAStakeRegistryTypes.Quorum memory invalidQuorum = IECDSAStakeRegistryTypes.Quorum({ + strategies: new IECDSAStakeRegistryTypes.StrategyParams[](1) + }); + invalidQuorum.strategies[0] = IECDSAStakeRegistryTypes.StrategyParams({ /// TODO: Make mock strategy strategy: IStrategy(address(420)), multiplier: 5000 // This should cause the update to revert as it's not the total required @@ -105,14 +114,18 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { operators[0] = operator1; operators[1] = operator2; - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InvalidQuorum.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InvalidQuorum.selector); registry.updateQuorumConfig(invalidQuorum, operators); } function test_RevertsWhen_NotOwner_UpdateQuorumConfig() public { - Quorum memory validQuorum = Quorum({strategies: new StrategyParams[](1)}); - validQuorum.strategies[0] = - StrategyParams({strategy: IStrategy(address(420)), multiplier: 10_000}); + IECDSAStakeRegistryTypes.Quorum memory validQuorum = IECDSAStakeRegistryTypes.Quorum({ + strategies: new IECDSAStakeRegistryTypes.StrategyParams[](1) + }); + validQuorum.strategies[0] = IECDSAStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(420)), + multiplier: 10_000 + }); address[] memory operators = new address[](2); operators[0] = operator1; @@ -126,7 +139,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { } function test_RevertsWhen_SameQuorum_UpdateQuorumConfig() public { - Quorum memory quorum = registry.quorum(); + IECDSAStakeRegistryTypes.Quorum memory quorum = registry.quorum(); address[] memory operators = new address[](2); operators[0] = operator1; operators[1] = operator2; @@ -136,7 +149,8 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { } function test_RevertSWhen_Duplicate_UpdateQuorumConfig() public { - Quorum memory invalidQuorum = Quorum({strategies: new StrategyParams[](2)}); + IECDSAStakeRegistryTypes.Quorum memory invalidQuorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](2)}); invalidQuorum.strategies[0] = StrategyParams({strategy: IStrategy(address(420)), multiplier: 5000}); address[] memory operators = new address[](2); @@ -145,12 +159,13 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { invalidQuorum.strategies[1] = StrategyParams({strategy: IStrategy(address(420)), multiplier: 5000}); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.NotSorted.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.NotSorted.selector); registry.updateQuorumConfig(invalidQuorum, operators); } function test_RevertSWhen_NotSorted_UpdateQuorumConfig() public { - Quorum memory invalidQuorum = Quorum({strategies: new StrategyParams[](2)}); + IECDSAStakeRegistryTypes.Quorum memory invalidQuorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](2)}); invalidQuorum.strategies[0] = StrategyParams({strategy: IStrategy(address(420)), multiplier: 5000}); address[] memory operators = new address[](2); @@ -159,19 +174,20 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { invalidQuorum.strategies[1] = StrategyParams({strategy: IStrategy(address(419)), multiplier: 5000}); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.NotSorted.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.NotSorted.selector); registry.updateQuorumConfig(invalidQuorum, operators); } function test_RevertSWhen_OverMultiplierTotal_UpdateQuorumConfig() public { - Quorum memory invalidQuorum = Quorum({strategies: new StrategyParams[](1)}); + IECDSAStakeRegistryTypes.Quorum memory invalidQuorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](1)}); invalidQuorum.strategies[0] = StrategyParams({strategy: IStrategy(address(420)), multiplier: 10_001}); address[] memory operators = new address[](2); operators[0] = operator1; operators[1] = operator2; - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InvalidQuorum.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InvalidQuorum.selector); registry.updateQuorumConfig(invalidQuorum, operators); } @@ -189,7 +205,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { assertEq(registry.getLastCheckpointTotalWeight(), 2000); ISignatureUtils.SignatureWithSaltAndExpiry memory signature; - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.OperatorAlreadyRegistered.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.OperatorAlreadyRegistered.selector); vm.prank(operator1); registry.registerOperatorWithSignature(signature, operator1); } @@ -225,7 +241,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { function test_RevertsWhen_NotOperator_DeregisterOperator() public { address notOperator = address(0x2); vm.prank(notOperator); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.OperatorNotRegistered.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.OperatorNotRegistered.selector); registry.deregisterOperator(); } @@ -302,7 +318,8 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { IStrategy mockStrategy = IStrategy(address(420)); IStrategy mockStrategy2 = IStrategy(address(421)); - Quorum memory quorum = Quorum({strategies: new StrategyParams[](2)}); + IECDSAStakeRegistryTypes.Quorum memory quorum = + IECDSAStakeRegistryTypes.Quorum({strategies: new StrategyParams[](2)}); quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 5000}); quorum.strategies[1] = StrategyParams({strategy: mockStrategy2, multiplier: 5000}); @@ -421,7 +438,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { (uint8 v, bytes32 r, bytes32 s) = vm.sign(operator1Pk, msgHash); signatures[0] = abi.encode(v, r, s); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.LengthMismatch.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.LengthMismatch.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, block.number - 1)); } @@ -430,7 +447,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { address[] memory signers = new address[](0); bytes[] memory signatures = new bytes[](0); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InvalidLength.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InvalidLength.selector); registry.isValidSignature(dataHash, abi.encode(signers, signatures, block.number - 1)); } @@ -445,7 +462,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { (v, r, s) = vm.sign(operator2Pk, msgHash); signatures[0] = abi.encodePacked(r, s, v); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.NotSorted.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.NotSorted.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, block.number - 1)); } @@ -463,7 +480,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { signatures[0] = abi.encodePacked(r, s, v); signatures[1] = abi.encodePacked(r, s, v); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.NotSorted.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.NotSorted.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, block.number - 1)); } @@ -474,7 +491,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { bytes[] memory signatures = new bytes[](1); signatures[0] = "invalid-signature"; - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InvalidSignature.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InvalidSignature.selector); registry.isValidSignature(dataHash, abi.encode(signers, signatures, block.number - 1)); } @@ -502,7 +519,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { abi.encode(50) ); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InsufficientSignedStake.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InsufficientSignedStake.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, block.number - 1)); } @@ -514,7 +531,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { signers[1] = operator2; bytes[] memory signatures = new bytes[](1); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.LengthMismatch.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.LengthMismatch.selector); registry.isValidSignature(dataHash, abi.encode(signers, signatures, referenceBlock)); } @@ -524,7 +541,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { address[] memory signers = new address[](0); bytes[] memory signatures = new bytes[](0); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InvalidLength.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InvalidLength.selector); registry.isValidSignature(dataHash, abi.encode(signers, signatures, referenceBlock)); } @@ -541,7 +558,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { (v, r, s) = vm.sign(operator2Pk, msgHash); signatures[0] = abi.encodePacked(r, s, v); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.NotSorted.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.NotSorted.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, referenceBlock)); } @@ -570,7 +587,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { abi.encode(50) ); - vm.expectRevert(ECDSAStakeRegistryEventsAndErrors.InsufficientSignedStake.selector); + vm.expectRevert(IECDSAStakeRegistryErrors.InsufficientSignedStake.selector); registry.isValidSignature(msgHash, abi.encode(signers, signatures, referenceBlock)); } @@ -643,7 +660,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { registry.registerOperatorWithSignature(operatorSignature, signer); // Verify that the signing key has been successfully registered for the operator - address registeredSigningKey = registry.getLastestOperatorSigningKey(operator); + address registeredSigningKey = registry.getLatestOperatorSigningKey(operator); assertEq( registeredSigningKey, signer, @@ -665,7 +682,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { registry.updateOperatorSigningKey(address(420)); // Verify that the signing key has been successfully registered for the operator - address registeredSigningKey = registry.getLastestOperatorSigningKey(operator); + address registeredSigningKey = registry.getLatestOperatorSigningKey(operator); vm.roll(block.number + 1); registeredSigningKey = diff --git a/test/unit/EjectionManagerUnit.t.sol b/test/unit/EjectionManagerUnit.t.sol index 2cfa859e..4a998468 100644 --- a/test/unit/EjectionManagerUnit.t.sol +++ b/test/unit/EjectionManagerUnit.t.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.27; import {EjectionManager} from "../../src/EjectionManager.sol"; -import {IEjectionManager, IEjectionManagerErrors} from "../../src/interfaces/IEjectionManager.sol"; - +import { + IEjectionManager, + IEjectionManagerErrors, + IEjectionManagerTypes +} from "../../src/interfaces/IEjectionManager.sol"; import "../utils/MockAVSDeployer.sol"; contract EjectionManagerUnitTests is MockAVSDeployer { @@ -18,7 +21,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { EjectionManager public ejectionManager; IEjectionManager public ejectionManagerImplementation; - IEjectionManager.QuorumEjectionParams[] public quorumEjectionParams; + IEjectionManagerTypes.QuorumEjectionParams[] public quorumEjectionParams; uint32 public ratelimitWindow = 1 days; uint16 public ejectableStakePercent = 1000; @@ -26,7 +29,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { function setUp() public virtual { for (uint8 i = 0; i < numQuorums; i++) { quorumEjectionParams.push( - IEjectionManager.QuorumEjectionParams({ + IEjectionManagerTypes.QuorumEjectionParams({ rateLimitWindow: ratelimitWindow, ejectableStakePercent: ejectableStakePercent }) @@ -82,7 +85,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { assertEq( uint8(registryCoordinator.getOperatorStatus(defaultOperator)), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); for (uint8 i = 0; i < numQuorums; i++) { @@ -97,7 +100,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { assertEq( uint8(registryCoordinator.getOperatorStatus(defaultOperator)), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } @@ -119,7 +122,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -136,7 +139,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } } @@ -160,7 +163,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -177,14 +180,14 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsCanEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } for (uint8 i = operatorsCanEject; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } } @@ -207,7 +210,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -224,7 +227,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } @@ -247,7 +250,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { _incrementAddress(defaultOperator, operatorsToEject + i) ) ), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -268,7 +271,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { _incrementAddress(defaultOperator, operatorsToEject + i) ) ), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } } @@ -298,7 +301,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -315,7 +318,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } } @@ -338,7 +341,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -355,7 +358,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } } @@ -381,7 +384,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 1; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.REGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.REGISTERED) ); } @@ -398,7 +401,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { for (uint8 i = 0; i < operatorsToEject; i++) { assertEq( uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), - uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED) + uint8(IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) ); } } @@ -407,8 +410,8 @@ contract EjectionManagerUnitTests is MockAVSDeployer { uint8 quorumNumber = 0; ratelimitWindow = 2 days; ejectableStakePercent = 2000; - IEjectionManager.QuorumEjectionParams memory _quorumEjectionParams = IEjectionManager - .QuorumEjectionParams({ + IEjectionManagerTypes.QuorumEjectionParams memory _quorumEjectionParams = + IEjectionManagerTypes.QuorumEjectionParams({ rateLimitWindow: ratelimitWindow, ejectableStakePercent: ejectableStakePercent }); @@ -452,7 +455,7 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(registryCoordinatorOwner); ejectionManager.setQuorumEjectionParams( 0, - IEjectionManager.QuorumEjectionParams({ + IEjectionManagerTypes.QuorumEjectionParams({ rateLimitWindow: 7 days, ejectableStakePercent: 9999 }) diff --git a/test/unit/IndexRegistryUnit.t.sol b/test/unit/IndexRegistryUnit.t.sol index 8846ff9d..0a6d424c 100644 --- a/test/unit/IndexRegistryUnit.t.sol +++ b/test/unit/IndexRegistryUnit.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.27; import "../../src/interfaces/IIndexRegistry.sol"; import "../../src/IndexRegistry.sol"; import "../harnesses/BitmapUtilsWrapper.sol"; -import {IIndexRegistryEvents} from "../events/IIndexRegistryEvents.sol"; +import {IIndexRegistryEvents} from "../../src/interfaces/IIndexRegistry.sol"; import "../utils/MockAVSDeployer.sol"; diff --git a/test/unit/OperatorStateRetrieverUnit.t.sol b/test/unit/OperatorStateRetrieverUnit.t.sol index e16621fc..34b59322 100644 --- a/test/unit/OperatorStateRetrieverUnit.t.sol +++ b/test/unit/OperatorStateRetrieverUnit.t.sol @@ -81,17 +81,19 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer { function test_getOperatorState_revert_quorumNotCreatedAtReferenceBlockNumber() public { cheats.roll(registrationBlockNumber); - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake }); uint96 minimumStake = 1; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1000)), multiplier: 1e16}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1000)), + multiplier: 1e16 + }); cheats.prank(registryCoordinator.owner()); registryCoordinator.createTotalDelegatedStakeQuorum( @@ -223,17 +225,19 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer { bytes32[] memory nonSignerOperatorIds = new bytes32[](1); nonSignerOperatorIds[0] = defaultOperatorId; - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake }); uint96 minimumStake = 1; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1000)), multiplier: 1e16}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1000)), + multiplier: 1e16 + }); cheats.prank(registryCoordinator.owner()); registryCoordinator.createTotalDelegatedStakeQuorum( diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index 3b62098d..bf6fb3a5 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -35,7 +35,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { event QuorumIndexUpdate(bytes32 indexed operatorId, uint8 quorumNumber, uint32 newIndex); event OperatorSetParamsUpdated( - uint8 indexed quorumNumber, IRegistryCoordinator.OperatorSetParam operatorSetParams + uint8 indexed quorumNumber, IRegistryCoordinatorTypes.OperatorSetParam operatorSetParams ); event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); @@ -57,7 +57,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { returns ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) { uint32 kickRegistrationBlockNumber = 100; @@ -82,7 +82,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { address operatorToKick; // register last operator before kick - operatorKickParams = new IRegistryCoordinator.OperatorKickParam[](1); + operatorKickParams = new IRegistryCoordinatorTypes.OperatorKickParam[](1); { BN254.G1Point memory pubKey = BN254.hashToG1( keccak256(abi.encodePacked(pseudoRandomNumber, defaultMaxOperatorCount - 1)) @@ -99,7 +99,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { // operatorIdsToSwap[0] = operatorToRegisterId operatorIdsToSwap[0] = operatorToRegisterId; - operatorKickParams[0] = IRegistryCoordinator.OperatorKickParam({ + operatorKickParams[0] = IRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: uint8(quorumNumbers[0]), operator: operatorToKick }); @@ -132,8 +132,8 @@ contract RegistryCoordinatorUnitTests_Initialization_Setters is RegistryCoordina 0, /*initialPausedStatus*/ operatorSetParams, new uint96[](0), - new IStakeRegistry.StrategyParams[][](0), - new StakeType[](0), + new IStakeRegistryTypes.StrategyParams[][](0), + new IStakeRegistryTypes.StakeType[](0), new uint32[](0) ); } @@ -208,9 +208,9 @@ contract RegistryCoordinatorUnitTests_Initialization_Setters is RegistryCoordina } function test_createQuorum_revert_notOwner() public { - IRegistryCoordinator.OperatorSetParam memory operatorSetParams; + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams; uint96 minimumStake; - IStakeRegistry.StrategyParams[] memory strategyParams; + IStakeRegistryTypes.StrategyParams[] memory strategyParams; cheats.expectRevert("Ownable: caller is not the owner"); cheats.prank(defaultOperator); @@ -224,17 +224,19 @@ contract RegistryCoordinatorUnitTests_Initialization_Setters is RegistryCoordina // this is necessary since the default setup already configures the max number of quorums, preventing adding more _deployMockEigenLayerAndAVS(0); - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake }); uint96 minimumStake = 1; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1000)), multiplier: 1e16}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1000)), + multiplier: 1e16 + }); uint8 quorumCountBefore = registryCoordinator.quorumCount(); @@ -342,9 +344,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -356,7 +358,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -413,9 +415,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -427,7 +429,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -480,9 +482,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -494,7 +496,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers)), updateBlockNumber: uint32(registrationBlockNumber), nextUpdateBlockNumber: uint32(nextRegistrationBlockNumber) @@ -508,7 +510,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: uint32(nextRegistrationBlockNumber), nextUpdateBlockNumber: 0 @@ -645,9 +647,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -659,7 +661,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -752,9 +754,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -766,7 +768,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: registrationBlockNumber, nextUpdateBlockNumber: deregistrationBlockNumber @@ -821,9 +823,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -835,7 +837,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: registrationBlockNumber, nextUpdateBlockNumber: deregistrationBlockNumber @@ -902,9 +904,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -914,9 +916,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -935,7 +937,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(registrationQuorumBitmap), updateBlockNumber: registrationBlockNumber, nextUpdateBlockNumber: deregistrationBlockNumber @@ -953,7 +955,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(expectedQuorumBitmap), updateBlockNumber: deregistrationBlockNumber, nextUpdateBlockNumber: 0 @@ -1038,9 +1040,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(operatorToDeregister))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: operatorToDeregisterId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -1054,7 +1056,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(operatorToDeregisterQuorumBitmap), updateBlockNumber: registrationBlockNumber, nextUpdateBlockNumber: deregistrationBlockNumber @@ -1079,7 +1081,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is cheats.roll(reregistrationBlockNumber); // store data before registering, to check against later - IRegistryCoordinator.QuorumBitmapUpdate memory previousQuorumBitmapUpdate = + IRegistryCoordinatorTypes.QuorumBitmapUpdate memory previousQuorumBitmapUpdate = registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0); // re-register the operator @@ -1093,9 +1095,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ), @@ -1122,7 +1124,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: uint32(reregistrationBlockNumber), nextUpdateBlockNumber: 0 @@ -1305,9 +1307,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -1317,9 +1319,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -1338,7 +1340,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(registrationQuorumBitmap), updateBlockNumber: registrationBlockNumber, nextUpdateBlockNumber: deregistrationBlockNumber @@ -1356,7 +1358,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(expectedQuorumBitmap), updateBlockNumber: deregistrationBlockNumber, nextUpdateBlockNumber: 0 @@ -1395,9 +1397,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -1440,9 +1442,9 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: defaultOperatorId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -1676,8 +1678,8 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord address operatorToKick; // register last operator before kick - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams = - new IRegistryCoordinator.OperatorKickParam[](1); + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams = + new IRegistryCoordinatorTypes.OperatorKickParam[](1); { BN254.G1Point memory pubKey = BN254.hashToG1(keccak256(abi.encodePacked(pseudoRandomNumber, numOperators - 1))); @@ -1690,7 +1692,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord // operatorIdsToSwap[0] = operatorToRegisterId operatorIdsToSwap[0] = operatorToRegisterId; - operatorKickParams[0] = IRegistryCoordinator.OperatorKickParam({ + operatorKickParams[0] = IRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: defaultQuorumNumber, operator: operatorToKick }); @@ -1753,9 +1755,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord keccak256(abi.encode(registryCoordinator.getOperator(operatorToRegister))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: operatorToRegisterId, - status: IRegistryCoordinator.OperatorStatus.REGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.REGISTERED }) ) ) @@ -1764,9 +1766,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord keccak256(abi.encode(registryCoordinator.getOperator(operatorToKick))), keccak256( abi.encode( - IRegistryCoordinator.OperatorInfo({ + IRegistryCoordinatorTypes.OperatorInfo({ operatorId: operatorToKickId, - status: IRegistryCoordinator.OperatorStatus.DEREGISTERED + status: IRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED }) ) ) @@ -1777,7 +1779,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(quorumBitmap), updateBlockNumber: kickRegistrationBlockNumber, nextUpdateBlockNumber: registrationBlockNumber @@ -1797,7 +1799,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); @@ -1835,7 +1837,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp( pseudoRandomNumber, quorumNumbers, operatorToKickStake ); @@ -1879,7 +1881,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, , - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); uint96 registeringStake = defaultKickBIPsOfOperatorStake * defaultStake; @@ -1913,7 +1915,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); @@ -2243,7 +2245,7 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(newBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -2267,7 +2269,7 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(newBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -2295,7 +2297,7 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(pastBitmap), updateBlockNumber: uint32(previousBlockNumber), nextUpdateBlockNumber: uint32(block.number) @@ -2309,7 +2311,7 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit ), keccak256( abi.encode( - IRegistryCoordinator.QuorumBitmapUpdate({ + IRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(newBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -2340,17 +2342,19 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit function test_CreateTotalDelegatedStakeQuorum() public { _deployMockEigenLayerAndAVS(0); // Set up test params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 0, kickBIPsOfTotalStake: 0 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(0x1)), multiplier: 1000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(0x1)), + multiplier: 1000 + }); // Get initial quorum count uint8 initialQuorumCount = registryCoordinator.quorumCount(); @@ -2365,7 +2369,7 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit assertEq(registryCoordinator.quorumCount(), initialQuorumCount + 1); // Verify quorum params were set correctly - IRegistryCoordinator.OperatorSetParam memory storedParams = + IRegistryCoordinatorTypes.OperatorSetParam memory storedParams = registryCoordinator.getOperatorSetParams(initialQuorumCount); assertEq(storedParams.maxOperatorCount, operatorSetParams.maxOperatorCount); assertEq(storedParams.kickBIPsOfOperatorStake, operatorSetParams.kickBIPsOfOperatorStake); @@ -2374,17 +2378,19 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit function test_CreateSlashableStakeQuorum_Reverts() public { _deployMockEigenLayerAndAVS(0); - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 0, kickBIPsOfTotalStake: 0 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(0x1)), multiplier: 1000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(0x1)), + multiplier: 1000 + }); uint32 lookAheadPeriod = 100; // Attempt to create quorum with slashable stake type before enabling operator sets @@ -2420,8 +2426,8 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT ISignatureUtils.SignatureWithSaltAndExpiry memory emptySignature = ISignatureUtils .SignatureWithSaltAndExpiry({signature: new bytes(0), salt: bytes32(0), expiry: 0}); - IBLSApkRegistry.PubkeyRegistrationParams memory operatorRegisterApkParams = IBLSApkRegistry - .PubkeyRegistrationParams({ + IBLSApkRegistryTypes.PubkeyRegistrationParams memory operatorRegisterApkParams = + IBLSApkRegistryTypes.PubkeyRegistrationParams({ pubkeyRegistrationSignature: BN254.G1Point({X: 0, Y: 0}), pubkeyG1: BN254.G1Point({X: 0, Y: 0}), pubkeyG2: BN254.G2Point({X: [uint256(0), uint256(0)], Y: [uint256(0), uint256(0)]}) @@ -2451,11 +2457,11 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT assertEq(bitmap, 0, "Operator bitmap should be empty after deregistration"); // Verify operator status is NEVER_REGISTERED - IRegistryCoordinator.OperatorStatus status = + IRegistryCoordinatorTypes.OperatorStatus status = registryCoordinator.getOperatorStatus(operatorToRegister); assertEq( uint8(status), - uint8(IRegistryCoordinator.OperatorStatus.NEVER_REGISTERED), + uint8(IRegistryCoordinatorTypes.OperatorStatus.NEVER_REGISTERED), "Operator status should be NEVER_REGISTERED" ); } @@ -2466,7 +2472,7 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(uint8(0)); - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature; cheats.expectRevert(); @@ -2484,17 +2490,17 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 1}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 1}); uint32 lookAheadPeriod = 100; // Create slashable stake quorum @@ -2513,17 +2519,19 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2541,18 +2549,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2562,9 +2572,9 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT operatorSetIds[0] = 0; string memory socket = "socket"; - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; // TODO: - // params = IBLSApkRegistry.PubkeyRegistrationParams({ + // params = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyG1: defaultPubKey, // pubkeyG2: defaultPubKeyG2, // pubkeySignature: defaultPubKeySignature @@ -2583,18 +2593,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2604,18 +2616,18 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT operatorSetIds[0] = 0; string memory socket = "socket"; - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; // TODO: - // params = IBLSApkRegistry.PubkeyRegistrationParams({ + // params = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyG1: defaultPubKey, // pubkeyG2: defaultPubKeyG2, // pubkeySignature: defaultPubKeySignature // }); - IRegistryCoordinator.OperatorKickParam[] memory operatorKickParams = - new IRegistryCoordinator.OperatorKickParam[](1); + IRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams = + new IRegistryCoordinatorTypes.OperatorKickParam[](1); operatorKickParams[0] = - IRegistryCoordinator.OperatorKickParam({operator: address(0x1), quorumNumber: 0}); + IRegistryCoordinatorTypes.OperatorKickParam({operator: address(0x1), quorumNumber: 0}); ISignatureUtils.SignatureWithSaltAndExpiry memory churnApproverSignature; ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature; @@ -2633,18 +2645,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT vm.skip(true); _deployMockEigenLayerAndAVS(0); - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); cheats.prank(registryCoordinatorOwner); registryCoordinator.createTotalDelegatedStakeQuorum( @@ -2663,18 +2677,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2685,9 +2701,9 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT operatorSetIds[0] = 0; string memory socket = "socket"; - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; // TODO: - // params = IBLSApkRegistry.PubkeyRegistrationParams({ + // params = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyG1: defaultPubKey, // pubkeyG2: defaultPubKeyG2, // pubkeySignature: defaultPubKeySignature @@ -2710,18 +2726,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2731,9 +2749,9 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT operatorSetIds[0] = 0; string memory socket = "socket"; - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; // TODO: - // params = IBLSApkRegistry.PubkeyRegistrationParams({ + // params = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyG1: defaultPubKey, // pubkeyG2: defaultPubKeyG2, // pubkeySignature: defaultPubKeySignature @@ -2752,18 +2770,20 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - IRegistryCoordinator.OperatorSetParam memory operatorSetParams = IRegistryCoordinator - .OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: 10, kickBIPsOfOperatorStake: 1000, kickBIPsOfTotalStake: 100 }); uint96 minimumStake = 100; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = - IStakeRegistry.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10_000}); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams({ + strategy: IStrategy(address(1)), + multiplier: 10_000 + }); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2774,9 +2794,9 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT operatorSetIds[0] = 0; string memory socket = "socket"; - IBLSApkRegistry.PubkeyRegistrationParams memory params; + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params; // TODO: - // params = IBLSApkRegistry.PubkeyRegistrationParams({ + // params = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyG1: defaultPubKey, // pubkeyG2: defaultPubKeyG2, // pubkeySignature: defaultPubKeySignature diff --git a/test/unit/StakeRegistryUnit.t.sol b/test/unit/StakeRegistryUnit.t.sol index ef479d7e..ddd8ee1e 100644 --- a/test/unit/StakeRegistryUnit.t.sol +++ b/test/unit/StakeRegistryUnit.t.sol @@ -99,9 +99,9 @@ contract StakeRegistryUnitTests is MockAVSDeployer, IStakeRegistryEvents { ) internal { uint8 quorumNumber = nextQuorum; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = IStakeRegistry.StrategyParams( + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(quorumNumber)))))), uint96(WEIGHTING_DIVISOR) ); @@ -111,8 +111,12 @@ contract StakeRegistryUnitTests is MockAVSDeployer, IStakeRegistryEvents { cheats.prank(address(registryCoordinator)); stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); - StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); - assertEq(uint8(stakeType), uint8(StakeType.TOTAL_DELEGATED), "invalid stake type"); + IStakeRegistryTypes.StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); + assertEq( + uint8(stakeType), + uint8(IStakeRegistryTypes.StakeType.TOTAL_DELEGATED), + "invalid stake type" + ); // Mark quorum initialized for other tests initializedQuorumBitmap = uint192(initializedQuorumBitmap.setBit(quorumNumber)); @@ -127,10 +131,10 @@ contract StakeRegistryUnitTests is MockAVSDeployer, IStakeRegistryEvents { function _initializeQuorum(uint96 minimumStake, uint256 numStrats) internal returns (uint8) { uint8 quorumNumber = nextQuorum; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](numStrats); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](numStrats); for (uint256 i = 0; i < strategyParams.length; i++) { - strategyParams[i] = IStakeRegistry.StrategyParams( + strategyParams[i] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(quorumNumber, i)))))), uint96(WEIGHTING_DIVISOR) ); @@ -587,7 +591,7 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { function testFuzz_initializeQuorum_Revert_WhenNotRegistryCoordinator( uint8 quorumNumber, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) public { cheats.expectRevert(IStakeRegistryErrors.OnlyRegistryCoordinator.selector); stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); @@ -596,7 +600,7 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { function testFuzz_initializeQuorum_Revert_WhenQuorumAlreadyExists( uint8 quorumNumber, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) public fuzzOnlyInitializedQuorums(quorumNumber) { cheats.expectRevert(IStakeRegistryErrors.QuorumAlreadyExists.selector); cheats.prank(address(registryCoordinator)); @@ -608,15 +612,15 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { uint96 minimumStake ) public { cheats.assume(quorumNumber >= nextQuorum); - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](0); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](0); cheats.expectRevert(IStakeRegistryErrors.InputArrayLengthZero.selector); cheats.prank(address(registryCoordinator)); stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); - strategyParams = new IStakeRegistry.StrategyParams[](MAX_WEIGHING_FUNCTION_LENGTH + 1); + strategyParams = new IStakeRegistryTypes.StrategyParams[](MAX_WEIGHING_FUNCTION_LENGTH + 1); for (uint256 i = 0; i < strategyParams.length; i++) { - strategyParams[i] = IStakeRegistry.StrategyParams( + strategyParams[i] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(i)))))), uint96(1) ); } @@ -625,46 +629,54 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); } - event StakeTypeSet(StakeType newStakeType); + event StakeTypeSet(IStakeRegistryTypes.StakeType newStakeType); function test_initializeDelegatedStakeQuorum() public { uint8 quorumNumber = nextQuorum; uint96 minimumStake = 0; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = IStakeRegistry.StrategyParams( + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(quorumNumber)))))), uint96(WEIGHTING_DIVISOR) ); cheats.prank(address(registryCoordinator)); cheats.expectEmit(true, true, true, true); - emit StakeTypeSet(StakeType.TOTAL_DELEGATED); + emit StakeTypeSet(IStakeRegistryTypes.StakeType.TOTAL_DELEGATED); stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); - StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); - assertEq(uint8(stakeType), uint8(StakeType.TOTAL_DELEGATED), "invalid stake type"); + IStakeRegistryTypes.StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); + assertEq( + uint8(stakeType), + uint8(IStakeRegistryTypes.StakeType.TOTAL_DELEGATED), + "invalid stake type" + ); } function test_initializeSlashableStakeQuorum() public { uint8 quorumNumber = nextQuorum; uint96 minimumStake = 0; - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](1); - strategyParams[0] = IStakeRegistry.StrategyParams( + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](1); + strategyParams[0] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(quorumNumber)))))), uint96(WEIGHTING_DIVISOR) ); cheats.prank(address(registryCoordinator)); cheats.expectEmit(true, true, true, true); - emit StakeTypeSet(StakeType.TOTAL_SLASHABLE); + emit StakeTypeSet(IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE); stakeRegistry.initializeSlashableStakeQuorum( quorumNumber, minimumStake, 7 days, strategyParams ); - StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); - assertEq(uint8(stakeType), uint8(StakeType.TOTAL_SLASHABLE), "invalid stake type"); + IStakeRegistryTypes.StakeType stakeType = stakeRegistry.stakeTypePerQuorum(quorumNumber); + assertEq( + uint8(stakeType), + uint8(IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE), + "invalid stake type" + ); } /** @@ -678,11 +690,11 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { ) public { cheats.assume(quorumNumber >= nextQuorum); cheats.assume(0 < multipliers.length && multipliers.length <= MAX_WEIGHING_FUNCTION_LENGTH); - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](multipliers.length); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](multipliers.length); for (uint256 i = 0; i < strategyParams.length; i++) { cheats.assume(multipliers[i] > 0); - strategyParams[i] = IStakeRegistry.StrategyParams( + strategyParams[i] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(i)))))), multipliers[i] ); } @@ -768,7 +780,7 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { */ function testFuzz_addStrategies_Revert_WhenNotRegistryCoordinatorOwner( uint8 quorumNumber, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) public fuzzOnlyInitializedQuorums(quorumNumber) { cheats.expectRevert(IStakeRegistryErrors.OnlyRegistryCoordinatorOwner.selector); stakeRegistry.addStrategies(quorumNumber, strategyParams); @@ -776,7 +788,7 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { function testFuzz_addStrategies_Revert_WhenInvalidQuorum( uint8 quorumNumber, - IStakeRegistry.StrategyParams[] memory strategyParams + IStakeRegistryTypes.StrategyParams[] memory strategyParams ) public { // quorums [0,nextQuorum) are initialized, so use an invalid quorumNumber cheats.assume(quorumNumber >= nextQuorum); @@ -790,10 +802,10 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { IStrategy strat = IStrategy(address(uint160(uint256(keccak256(abi.encodePacked("duplicate strat")))))); - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](2); - strategyParams[0] = IStakeRegistry.StrategyParams(strat, uint96(WEIGHTING_DIVISOR)); - strategyParams[1] = IStakeRegistry.StrategyParams(strat, uint96(WEIGHTING_DIVISOR)); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](2); + strategyParams[0] = IStakeRegistryTypes.StrategyParams(strat, uint96(WEIGHTING_DIVISOR)); + strategyParams[1] = IStakeRegistryTypes.StrategyParams(strat, uint96(WEIGHTING_DIVISOR)); cheats.expectRevert(IStakeRegistryErrors.InputDuplicateStrategy.selector); cheats.prank(registryCoordinatorOwner); @@ -805,9 +817,9 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { IStrategy strat = IStrategy(address(uint160(uint256(keccak256(abi.encodePacked("duplicate strat")))))); - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](2); - strategyParams[0] = IStakeRegistry.StrategyParams(strat, 0); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](2); + strategyParams[0] = IStakeRegistryTypes.StrategyParams(strat, 0); cheats.expectRevert(IStakeRegistryErrors.InputMultiplierZero.selector); cheats.prank(registryCoordinatorOwner); @@ -832,11 +844,11 @@ contract StakeRegistryUnitTests_Config is StakeRegistryUnitTests { cheats.assume(multipliers[i] > 0); } // Expected events emitted - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](multipliers.length); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](multipliers.length); for (uint256 i = 0; i < strategyParams.length; i++) { IStrategy strat = IStrategy(address(uint160(uint256(keccak256(abi.encodePacked(i)))))); - strategyParams[i] = IStakeRegistry.StrategyParams(strat, multipliers[i]); + strategyParams[i] = IStakeRegistryTypes.StrategyParams(strat, multipliers[i]); cheats.expectEmit(true, true, true, true, address(stakeRegistry)); emit StrategyAddedToQuorum(quorumNumber, strat); @@ -1882,7 +1894,7 @@ contract StakeRegistryUnitTests_StakeUpdates is StakeRegistryUnitTests { "failed to remove delta from total stake" ); assertEq(newOperatorStake.stake, 0, "operator stake should now be zero"); - // Quorum should be added to return bitmap + // IECDSAStakeRegistryTypes.Quorum should be added to return bitmap assertTrue( quorumsToRemove.isSet(quorumNumber), "quorum should be in removal bitmap" ); @@ -2095,7 +2107,7 @@ contract StakeRegistryUnitTests_StakeUpdates is StakeRegistryUnitTests { ); // assertEq(prevTotalStake.stake - stakeRemoved, newTotalStake.stake, "failed to remove delta from total stake"); assertEq(newOperatorStake.stake, 0, "operator stake should now be zero"); - // Quorum should be added to return bitmap + // IECDSAStakeRegistryTypes.Quorum should be added to return bitmap assertTrue( quorumsToRemove.isSet(quorumNumber), "quorum should be in removal bitmap" ); @@ -2171,8 +2183,8 @@ contract StakeRegistryUnitTests_weightOfOperatorForQuorum is StakeRegistryUnitTe // Initialize quorum with strategies of fuzzed multipliers. // Bound multipliers and shares max values to prevent overflows - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](3); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](3); for (uint256 i = 0; i < strategyParams.length; i++) { multipliers[i] = uint96( _randUint({ @@ -2186,8 +2198,9 @@ contract StakeRegistryUnitTests_weightOfOperatorForQuorum is StakeRegistryUnitTe IStrategy strat = IStrategy( address(uint160(uint256(keccak256(abi.encodePacked("Voteweighing test", i))))) ); - strategyParams[i] = - IStakeRegistry.StrategyParams(strat, uint96(WEIGHTING_DIVISOR) + multipliers[i]); + strategyParams[i] = IStakeRegistryTypes.StrategyParams( + strat, uint96(WEIGHTING_DIVISOR) + multipliers[i] + ); } cheats.prank(address(registryCoordinator)); uint8 quorumNumber = nextQuorum; @@ -2227,14 +2240,14 @@ contract StakeRegistryUnitTests_weightOfOperatorForQuorum is StakeRegistryUnitTe multipliers[1] = uint96(1_071_364_636_818_145_808); multipliers[2] = uint96(1_000_000_000_000_000_000); - IStakeRegistry.StrategyParams[] memory strategyParams = - new IStakeRegistry.StrategyParams[](3); + IStakeRegistryTypes.StrategyParams[] memory strategyParams = + new IStakeRegistryTypes.StrategyParams[](3); for (uint256 i = 0; i < strategyParams.length; i++) { shares[i] = uint96(_randUint({rand: bytes32(uint256(shares[i])), min: 0, max: 1e24})); IStrategy strat = IStrategy( address(uint160(uint256(keccak256(abi.encodePacked("Voteweighing test", i))))) ); - strategyParams[i] = IStakeRegistry.StrategyParams(strat, multipliers[i]); + strategyParams[i] = IStakeRegistryTypes.StrategyParams(strat, multipliers[i]); } // create a valid quorum diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 15e6d425..102e5125 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -10,12 +10,14 @@ import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISi import {BitmapUtils} from "../../src/libraries/BitmapUtils.sol"; import {BN254} from "../../src/libraries/BN254.sol"; +import {IRegistryCoordinatorTypes} from "../../src/interfaces/IRegistryCoordinator.sol"; import {OperatorStateRetriever} from "../../src/OperatorStateRetriever.sol"; import {RegistryCoordinator} from "../../src/RegistryCoordinator.sol"; import {RegistryCoordinatorHarness} from "../harnesses/RegistryCoordinatorHarness.t.sol"; import {BLSApkRegistry} from "../../src/BLSApkRegistry.sol"; +import {IBLSApkRegistryTypes} from "../../src/interfaces/IBLSApkRegistry.sol"; import {ServiceManagerMock} from "../mocks/ServiceManagerMock.sol"; -import {StakeRegistry, StakeType} from "../../src/StakeRegistry.sol"; +import {StakeRegistry, IStakeRegistryTypes} from "../../src/StakeRegistry.sol"; import {IndexRegistry} from "../../src/IndexRegistry.sol"; import {IBLSApkRegistry} from "../../src/interfaces/IBLSApkRegistry.sol"; import {IStakeRegistry} from "../../src/interfaces/IStakeRegistry.sol"; @@ -122,7 +124,7 @@ contract MockAVSDeployer is Test { uint32 registrationBlockNumber = 100; uint32 blocksBetweenRegistrations = 10; - IBLSApkRegistry.PubkeyRegistrationParams pubkeyRegistrationParams; + IBLSApkRegistryTypes.PubkeyRegistrationParams pubkeyRegistrationParams; struct OperatorMetadata { uint256 quorumBitmap; @@ -271,11 +273,12 @@ contract MockAVSDeployer is Test { } // setup the dummy quorum strategies - IStakeRegistry.StrategyParams[][] memory quorumStrategiesConsideredAndMultipliers = - new IStakeRegistry.StrategyParams[][](numQuorumsToAdd); + IStakeRegistryTypes.StrategyParams[][] memory quorumStrategiesConsideredAndMultipliers = + new IStakeRegistryTypes.StrategyParams[][](numQuorumsToAdd); for (uint256 i = 0; i < quorumStrategiesConsideredAndMultipliers.length; i++) { - quorumStrategiesConsideredAndMultipliers[i] = new IStakeRegistry.StrategyParams[](1); - quorumStrategiesConsideredAndMultipliers[i][0] = IStakeRegistry.StrategyParams( + quorumStrategiesConsideredAndMultipliers[i] = + new IStakeRegistryTypes.StrategyParams[](1); + quorumStrategiesConsideredAndMultipliers[i][0] = IStakeRegistryTypes.StrategyParams( IStrategy(address(uint160(i))), uint96(WEIGHTING_DIVISOR) ); } @@ -293,7 +296,7 @@ contract MockAVSDeployer is Test { for (uint256 i = 0; i < numQuorumsToAdd; i++) { // hard code these for now operatorSetParams.push( - IRegistryCoordinator.OperatorSetParam({ + IRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake @@ -302,12 +305,13 @@ contract MockAVSDeployer is Test { } // Create arrays for quorum types and lookahead periods - StakeType[] memory quorumStakeTypes = new StakeType[](numQuorumsToAdd); + IStakeRegistryTypes.StakeType[] memory quorumStakeTypes = + new IStakeRegistryTypes.StakeType[](numQuorumsToAdd); uint32[] memory slashableStakeQuorumLookAheadPeriods = new uint32[](numQuorumsToAdd); // Set all quorums to TOTAL_DELEGATED type with 0 lookahead period for (uint256 i = 0; i < numQuorumsToAdd; i++) { - quorumStakeTypes[i] = StakeType.TOTAL_DELEGATED; + quorumStakeTypes[i] = IStakeRegistryTypes.StakeType.TOTAL_DELEGATED; slashableStakeQuorumLookAheadPeriods[i] = 0; }