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/BLSSignatureCheckerStorage.md b/docs/storage-report/BLSSignatureCheckerStorage.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/storage-report/ECDSAServiceManagerBase.md b/docs/storage-report/ECDSAServiceManagerBase.md index 2251f673..e69de29b 100644 --- a/docs/storage-report/ECDSAServiceManagerBase.md +++ b/docs/storage-report/ECDSAServiceManagerBase.md @@ -1,19 +0,0 @@ - -╭------------------+-------------+------+--------+-------+-------------------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+============================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| __gap | uint256[50] | 1 | 0 | 1600 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| _owner | address | 51 | 0 | 20 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| __gap | uint256[49] | 52 | 0 | 1568 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| rewardsInitiator | address | 101 | 0 | 20 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -|------------------+-------------+------+--------+-------+-------------------------------------------------------------------| -| __GAP | uint256[49] | 102 | 0 | 1568 | src/unaudited/ECDSAServiceManagerBase.sol:ECDSAServiceManagerBase | -╰------------------+-------------+------+--------+-------+-------------------------------------------------------------------╯ - diff --git a/docs/storage-report/ECDSAStakeRegistry.md b/docs/storage-report/ECDSAStakeRegistry.md index df768c27..e69de29b 100644 --- a/docs/storage-report/ECDSAStakeRegistry.md +++ b/docs/storage-report/ECDSAStakeRegistry.md @@ -1,37 +0,0 @@ - -╭----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+==========================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| __gap | uint256[50] | 1 | 0 | 1600 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _owner | address | 51 | 0 | 20 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| __gap | uint256[49] | 52 | 0 | 1568 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _serviceManager | address | 104 | 0 | 20 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _stakeExpiry | uint256 | 105 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _operatorSigningKeyHistory | mapping(address => struct CheckpointsUpgradeable.History) | 106 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _totalWeightHistory | struct CheckpointsUpgradeable.History | 107 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _thresholdWeightHistory | struct CheckpointsUpgradeable.History | 108 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _operatorWeightHistory | mapping(address => struct CheckpointsUpgradeable.History) | 109 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| _operatorRegistered | mapping(address => bool) | 110 | 0 | 32 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -|----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------| -| __gap | uint256[40] | 111 | 0 | 1280 | src/unaudited/ECDSAStakeRegistry.sol:ECDSAStakeRegistry | -╰----------------------------+-----------------------------------------------------------+------+--------+-------+---------------------------------------------------------╯ - diff --git a/docs/storage-report/ECDSAStakeRegistryEqualWeight.md b/docs/storage-report/ECDSAStakeRegistryEqualWeight.md index e1e1c166..e69de29b 100644 --- a/docs/storage-report/ECDSAStakeRegistryEqualWeight.md +++ b/docs/storage-report/ECDSAStakeRegistryEqualWeight.md @@ -1,39 +0,0 @@ - -╭----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+=========================================================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| __gap | uint256[50] | 1 | 0 | 1600 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _owner | address | 51 | 0 | 20 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| __gap | uint256[49] | 52 | 0 | 1568 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _serviceManager | address | 104 | 0 | 20 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _stakeExpiry | uint256 | 105 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _operatorSigningKeyHistory | mapping(address => struct CheckpointsUpgradeable.History) | 106 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _totalWeightHistory | struct CheckpointsUpgradeable.History | 107 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _thresholdWeightHistory | struct CheckpointsUpgradeable.History | 108 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _operatorWeightHistory | mapping(address => struct CheckpointsUpgradeable.History) | 109 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| _operatorRegistered | mapping(address => bool) | 110 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| __gap | uint256[40] | 111 | 0 | 1280 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -|----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------| -| allowlistedOperators | mapping(address => bool) | 151 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryEqualWeight.sol:ECDSAStakeRegistryEqualWeight | -╰----------------------------+-----------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------------╯ - diff --git a/docs/storage-report/ECDSAStakeRegistryPermissioned.md b/docs/storage-report/ECDSAStakeRegistryPermissioned.md index bdc5b32e..e69de29b 100644 --- a/docs/storage-report/ECDSAStakeRegistryPermissioned.md +++ b/docs/storage-report/ECDSAStakeRegistryPermissioned.md @@ -1,39 +0,0 @@ - -╭----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+===========================================================================================================================================================================================================+ -| _initialized | uint8 | 0 | 0 | 1 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _initializing | bool | 0 | 1 | 1 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| __gap | uint256[50] | 1 | 0 | 1600 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _owner | address | 51 | 0 | 20 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| __gap | uint256[49] | 52 | 0 | 1568 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _totalOperators | uint256 | 101 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _quorum | struct Quorum | 102 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _minimumWeight | uint256 | 103 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _serviceManager | address | 104 | 0 | 20 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _stakeExpiry | uint256 | 105 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _operatorSigningKeyHistory | mapping(address => struct CheckpointsUpgradeable.History) | 106 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _totalWeightHistory | struct CheckpointsUpgradeable.History | 107 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _thresholdWeightHistory | struct CheckpointsUpgradeable.History | 108 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _operatorWeightHistory | mapping(address => struct CheckpointsUpgradeable.History) | 109 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| _operatorRegistered | mapping(address => bool) | 110 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| __gap | uint256[40] | 111 | 0 | 1280 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -|----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------| -| allowlistedOperators | mapping(address => bool) | 151 | 0 | 32 | src/unaudited/examples/ECDSAStakeRegistryPermissioned.sol:ECDSAStakeRegistryPermissioned | -╰----------------------------+-----------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------------╯ - diff --git a/docs/storage-report/ECDSAStakeRegistryStorage.md b/docs/storage-report/ECDSAStakeRegistryStorage.md index 69ef3d05..e69de29b 100644 --- a/docs/storage-report/ECDSAStakeRegistryStorage.md +++ b/docs/storage-report/ECDSAStakeRegistryStorage.md @@ -1,27 +0,0 @@ - -╭----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+========================================================================================================================================================================================+ -| _totalOperators | uint256 | 0 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _quorum | struct Quorum | 1 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _minimumWeight | uint256 | 2 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _serviceManager | address | 3 | 0 | 20 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _stakeExpiry | uint256 | 4 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _operatorSigningKeyHistory | mapping(address => struct CheckpointsUpgradeable.History) | 5 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _totalWeightHistory | struct CheckpointsUpgradeable.History | 6 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _thresholdWeightHistory | struct CheckpointsUpgradeable.History | 7 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _operatorWeightHistory | mapping(address => struct CheckpointsUpgradeable.History) | 8 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| _operatorRegistered | mapping(address => bool) | 9 | 0 | 32 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -|----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------| -| __gap | uint256[40] | 10 | 0 | 1280 | src/unaudited/ECDSAStakeRegistryStorage.sol:ECDSAStakeRegistryStorage | -╰----------------------------+-----------------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------╯ - diff --git a/docs/storage-report/EjectionManagerStorage.md b/docs/storage-report/EjectionManagerStorage.md new file mode 100644 index 00000000..e69de29b diff --git a/docs/storage-report/RegistryCoordinatorStorage.md b/docs/storage-report/RegistryCoordinatorStorage.md index 47e30da8..e28515ac 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 | -|-------------------------+----------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| -| operatorSetsEnabled | 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 ISlashingRegistryCoordinatorTypes.OperatorSetParam) | 1 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| _operatorBitmapHistory | mapping(bytes32 => struct ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate[]) | 2 | 0 | 32 | src/RegistryCoordinatorStorage.sol:RegistryCoordinatorStorage | +|-------------------------+---------------------------------------------------------------------------+------+--------+-------+---------------------------------------------------------------| +| _operatorInfo | mapping(address => struct ISlashingRegistryCoordinatorTypes.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/ServiceManagerRouter.md b/docs/storage-report/ServiceManagerRouter.md index 1ec5dc07..e69de29b 100644 --- a/docs/storage-report/ServiceManagerRouter.md +++ b/docs/storage-report/ServiceManagerRouter.md @@ -1,6 +0,0 @@ - -╭------+------+------+--------+-------+----------╮ -| Name | Type | Slot | Offset | Bytes | Contract | -+================================================+ -╰------+------+------+--------+-------+----------╯ - diff --git a/foundry.toml b/foundry.toml index 7b02b1c8..ce96ecd1 100644 --- a/foundry.toml +++ b/foundry.toml @@ -74,7 +74,7 @@ # Quotation mark style quote_style = "double" # Options: "double", "single", "preserve" # Style of underscores in number literals - number_underscore = "thousands" # Options: "preserve", "thousands", "remove" + number_underscore = "remove" # Options: "preserve", "thousands", "remove" # Whether or not to wrap comments at line_length wrap_comments = false # List of files to ignore during formatting (can use glob patterns) diff --git a/src/BLSApkRegistry.sol b/src/BLSApkRegistry.sol index 65d125fb..831210ea 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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.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 @@ -52,18 +42,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { emit OperatorAddedToQuorums(operator, getOperatorId(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 @@ -76,10 +55,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { emit OperatorRemovedFromQuorums(operator, getOperatorId(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, @@ -107,7 +78,7 @@ contract BLSApkRegistry is BLSApkRegistryStorage { ) external onlyRegistryCoordinator returns (bytes32 operatorId) { bytes32 pubkeyHash = BN254.hashG1Point(params.pubkeyG1); require(pubkeyHash != ZERO_PK_HASH, ZeroPubKey()); - require(operatorToPubkeyHash[operator] == bytes32(0), OperatorAlreadyRegistered()); + require(getOperatorId(operator) == bytes32(0), OperatorAlreadyRegistered()); require(pubkeyHashToOperator[pubkeyHash] == address(0), BLSPubkeyAlreadyRegistered()); // gamma = h(sigma, P, P', H(m)) @@ -190,25 +161,20 @@ 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) { BN254.G1Point memory pubkey = operatorToPubkey[operator]; - bytes32 pubkeyHash = operatorToPubkeyHash[operator]; + bytes32 pubkeyHash = getOperatorId(operator); require(pubkeyHash != bytes32(0), OperatorNotRegistered()); 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 ffbd075d..2d07a1a9 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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.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( ISlashingRegistryCoordinator _slashingRegistryCoordinator @@ -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 aaaa094e..5743be64 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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.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; - - ISlashingRegistryCoordinator 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( ISlashingRegistryCoordinator _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..59bd073a --- /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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.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 = 120000; + + /// @inheritdoc IBLSSignatureChecker + ISlashingRegistryCoordinator 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( + ISlashingRegistryCoordinator _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 578a2222..c9078a81 100644 --- a/src/EjectionManager.sol +++ b/src/EjectionManager.sol @@ -2,46 +2,27 @@ pragma solidity ^0.8.27; import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import {IEjectionManager} from "./interfaces/IEjectionManager.sol"; -import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.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 - ISlashingRegistryCoordinator 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(ISlashingRegistryCoordinator _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, @@ -56,18 +37,13 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable { } } - /** - * @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..e8996cd6 --- /dev/null +++ b/src/EjectionManagerStorage.sol @@ -0,0 +1,34 @@ +// 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 = 10000; + /// @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; + } + + /// @dev This was missing before the slashing release, if your contract + /// was deployed pre-slashing, you should double check your storage layout. + uint256[47] private __gap; +} diff --git a/src/IndexRegistry.sol b/src/IndexRegistry.sol index ef9b0c49..032b1839 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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol"; /** @@ -9,13 +9,11 @@ import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordi * @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( ISlashingRegistryCoordinator _slashingRegistryCoordinator ) IndexRegistryStorage(_slashingRegistryCoordinator) {} @@ -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 5dade2dd..590b8386 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.27; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; -import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; +import {IBLSApkRegistry, IBLSApkRegistryTypes} from "./interfaces/IBLSApkRegistry.sol"; import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol"; import {IIndexRegistry} from "./interfaces/IIndexRegistry.sol"; import {IServiceManager} from "./interfaces/IServiceManager.sol"; @@ -12,6 +12,8 @@ import {IRegistryCoordinator} from "./interfaces/IRegistryCoordinator.sol"; import {BitmapUtils} from "./libraries/BitmapUtils.sol"; import {SlashingRegistryCoordinator} from "./SlashingRegistryCoordinator.sol"; +import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol"; +import {OwnableUpgradeable} from "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; /** * @title A `RegistryCoordinator` that has three registries: @@ -21,7 +23,7 @@ import {SlashingRegistryCoordinator} from "./SlashingRegistryCoordinator.sol"; * * @author Layr Labs, Inc. */ -contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinator { +contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinator { using BitmapUtils for *; /// @notice the ServiceManager for this AVS, which forwards calls onto EigenLayer's core contracts @@ -56,7 +58,7 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato 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(!m2QuorumsDisabled, M2QuorumsAlreadyDisabled()); @@ -104,7 +106,7 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato 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 @@ -143,12 +145,11 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato /// @inheritdoc IRegistryCoordinator function deregisterOperator( bytes memory quorumNumbers - ) external onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) { + ) external override onlyWhenNotPaused(PAUSED_DEREGISTER_OPERATOR) { // Check that the quorum numbers are M2 quorums for (uint256 i = 0; i < quorumNumbers.length; i++) { require( - !operatorSetsEnabled || _isM2Quorum(uint8(quorumNumbers[i])), - OperatorSetsAlreadyEnabled() + !operatorSetsEnabled || _isM2Quorum(uint8(quorumNumbers[i])), OperatorSetQuorum() ); } _deregisterOperator({operator: msg.sender, quorumNumbers: quorumNumbers}); @@ -203,4 +204,14 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, IRegistryCoordinato // This is a safe operation since we limit MAX_QUORUM_COUNT to 192 return (1 << quorumCount) - 1; } + + /// @dev need to override function here since its defined in both these contracts + function owner() + public + view + override(SlashingRegistryCoordinator, ISlashingRegistryCoordinator) + returns (address) + { + return OwnableUpgradeable.owner(); + } } diff --git a/src/SlashingRegistryCoordinator.sol b/src/SlashingRegistryCoordinator.sol index 605c4285..111a6d48 100644 --- a/src/SlashingRegistryCoordinator.sol +++ b/src/SlashingRegistryCoordinator.sol @@ -9,9 +9,9 @@ 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 {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol"; @@ -26,7 +26,6 @@ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/draft-EIP712.so import {Pausable} from "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; import {SlashingRegistryCoordinatorStorage} from "./SlashingRegistryCoordinatorStorage.sol"; -import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol"; /** * @title A `RegistryCoordinator` that has three registries: @@ -42,8 +41,6 @@ contract SlashingRegistryCoordinator is Pausable, OwnableUpgradeable, SlashingRegistryCoordinatorStorage, - IAVSRegistrar, - ISocketUpdater, ISignatureUtils { using BitmapUtils for *; @@ -130,15 +127,21 @@ contract SlashingRegistryCoordinator is 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 + ); } function createSlashableStakeQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, - IStakeRegistry.StrategyParams[] memory strategyParams, + IStakeRegistryTypes.StrategyParams[] memory strategyParams, uint32 lookAheadPeriod ) external virtual onlyOwner { require(operatorSetsEnabled, OperatorSetsNotEnabled()); @@ -146,7 +149,7 @@ contract SlashingRegistryCoordinator is operatorSetParams, minimumStake, strategyParams, - StakeType.TOTAL_SLASHABLE, + IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE, lookAheadPeriod ); } @@ -162,8 +165,10 @@ contract SlashingRegistryCoordinator is ( RegistrationType registrationType, string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params - ) = abi.decode(data, (RegistrationType, string, IBLSApkRegistry.PubkeyRegistrationParams)); + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params + ) = abi.decode( + data, (RegistrationType, string, IBLSApkRegistryTypes.PubkeyRegistrationParams) + ); /** * If the operator has NEVER registered a pubkey before, use `params` to register @@ -205,7 +210,7 @@ contract SlashingRegistryCoordinator is ( RegistrationType, string, - IBLSApkRegistry.PubkeyRegistrationParams, + IBLSApkRegistryTypes.PubkeyRegistrationParams, OperatorKickParam[], SignatureWithSaltAndExpiry ) @@ -666,7 +671,7 @@ contract SlashingRegistryCoordinator is */ function _getOrCreateOperatorId( address operator, - IBLSApkRegistry.PubkeyRegistrationParams memory params + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params ) internal returns (bytes32 operatorId) { operatorId = blsApkRegistry.getOperatorId(operator); if (operatorId == 0) { @@ -807,8 +812,8 @@ contract SlashingRegistryCoordinator 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 @@ -842,9 +847,9 @@ contract SlashingRegistryCoordinator is allocationManager.createOperatorSets({avs: accountIdentifier, params: createSetParams}); } // 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 ); @@ -1114,6 +1119,7 @@ contract SlashingRegistryCoordinator is function owner() public view + virtual override(OwnableUpgradeable, ISlashingRegistryCoordinator) returns (address) { diff --git a/src/SlashingRegistryCoordinatorStorage.sol b/src/SlashingRegistryCoordinatorStorage.sol index e8c9eb9b..421d1fbc 100644 --- a/src/SlashingRegistryCoordinatorStorage.sol +++ b/src/SlashingRegistryCoordinatorStorage.sol @@ -30,7 +30,7 @@ abstract contract SlashingRegistryCoordinatorStorage is ISlashingRegistryCoordin /// @notice The maximum value of a quorum bitmap uint256 internal constant MAX_QUORUM_BITMAP = type(uint192).max; /// @notice The basis point denominator - uint16 internal constant BIPS_DENOMINATOR = 10_000; + uint16 internal constant BIPS_DENOMINATOR = 10000; /// @notice Index for flag that pauses operator registration uint8 internal constant PAUSED_REGISTER_OPERATOR = 0; /// @notice Index for flag that pauses operator deregistration diff --git a/src/StakeRegistry.sol b/src/StakeRegistry.sol index a75625a0..4cf3a286 100644 --- a/src/StakeRegistry.sol +++ b/src/StakeRegistry.sol @@ -11,7 +11,7 @@ import {IAllocationManager} from import {StakeRegistryStorage, IStrategy} from "./StakeRegistryStorage.sol"; import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol"; -import {IStakeRegistry, StakeType} from "./interfaces/IStakeRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./interfaces/IStakeRegistry.sol"; import {BitmapUtils} from "./libraries/BitmapUtils.sol"; @@ -64,19 +64,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, @@ -109,18 +97,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 @@ -145,15 +122,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, @@ -199,7 +168,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, @@ -208,7 +177,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({ @@ -219,7 +188,7 @@ contract StakeRegistry is StakeRegistryStorage { ); } - /// @notice Initialize a new quorum and push its first history update + /// @inheritdoc IStakeRegistry function initializeSlashableStakeQuorum( uint8 quorumNumber, uint96 minimumStake, @@ -229,7 +198,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( @@ -241,6 +210,7 @@ contract StakeRegistry is StakeRegistryStorage { ); } + /// @inheritdoc IStakeRegistry function setMinimumStakeForQuorum( uint8 quorumNumber, uint96 minimumStake @@ -248,11 +218,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 @@ -260,12 +226,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 @@ -287,11 +248,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 @@ -329,12 +286,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, @@ -585,7 +537,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]; @@ -630,13 +582,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) { @@ -645,10 +591,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 @@ -657,14 +600,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 @@ -678,9 +621,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 @@ -688,11 +629,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 @@ -700,10 +637,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 @@ -712,10 +646,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 @@ -730,13 +661,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, @@ -745,7 +670,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, @@ -756,7 +681,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, @@ -765,16 +690,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, @@ -793,30 +709,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 @@ -824,14 +731,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, @@ -842,12 +742,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 @@ -879,7 +774,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 e13835f3..2c00aec2 100644 --- a/src/StakeRegistryStorage.sol +++ b/src/StakeRegistryStorage.sol @@ -12,7 +12,7 @@ import { } from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {ISlashingRegistryCoordinator} from "./interfaces/ISlashingRegistryCoordinator.sol"; -import {IStakeRegistry, StakeType} from "./interfaces/IStakeRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./interfaces/IStakeRegistry.sol"; /** * @title Storage variables for the `StakeRegistry` contract. @@ -25,7 +25,7 @@ abstract contract StakeRegistryStorage is IStakeRegistry { /// @notice Maximum length of dynamic arrays in the `strategyParams` mapping. uint8 public constant MAX_WEIGHING_FUNCTION_LENGTH = 32; /// @notice Constant used as a divisor in dealing with BIPS amounts. - uint256 internal constant MAX_BIPS = 10_000; + uint256 internal constant MAX_BIPS = 10000; /// @notice The address of the Delegation contract for EigenLayer. IDelegationManager public immutable delegation; @@ -58,8 +58,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..05a5c229 100644 --- a/src/interfaces/IBLSApkRegistry.sol +++ b/src/interfaces/IBLSApkRegistry.sol @@ -1,173 +1,245 @@ // 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 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 Registers the `operator`'s pubkey for the specified `quorumNumbers`. + /* + * @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 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 + * @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 duplicatesd + * 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`. + /* + * @notice Deregisters `operator`'s pubkey from `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 + * @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); + ) external view returns (IBLSApkRegistryTypes.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 + /* + * @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, @@ -175,9 +247,32 @@ interface IBLSApkRegistry is IRegistry, IBLSApkRegistryErrors { 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 87feab40..e7b78a04 100644 --- a/src/interfaces/IBLSSignatureChecker.sol +++ b/src/interfaces/IBLSSignatureChecker.sol @@ -8,86 +8,146 @@ 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 - - /// @notice Emitted when `staleStakesForbiddenUpdate` is set +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 (ISlashingRegistryCoordinator); + + /* + * @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 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 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. + * 1. Getting the aggregated pubkey of all registered nodes at the time of pre-commit by the + * disperser (represented by apk in the parameters) + * 2. Subtracting the pubkeys of all non-signers (nonSignerPubkeys) and storing + * the output in apk to get aggregated pubkey of all operators that are part of quorum + * 3. Using 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. + * @param msgHash The hash of the message that was signed. 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 The quorum numbers to verify signatures for, where each byte is an 8-bit integer. + * @param referenceBlockNumber The block number at which the stake information is being verified + * @param nonSignerStakesAndSignature Contains non-signer information and aggregated signature data. + * @return quorumStakeTotals The struct containing the total and signed stake for each quorum + * @return signatoryRecordHash The hash of the signatory record, which is used for fraud proofs + * @dev Before signature verification, the function verifies operator stake information. This includes + * ensuring that the provided referenceBlockNumber is valid and recent enough, and that the stake is + * either the most recent update for the total stake (of the operator) or latest before the referenceBlockNumber. */ function checkSignatures( bytes32 msgHash, @@ -95,4 +155,20 @@ interface IBLSSignatureChecker is IBLSSignatureCheckerErrors { 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..e17086f8 --- /dev/null +++ b/src/interfaces/IECDSAStakeRegistry.sol @@ -0,0 +1,305 @@ +// 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..5ead07cb 100644 --- a/src/interfaces/IEjectionManager.sol +++ b/src/interfaces/IEjectionManager.sol @@ -1,70 +1,152 @@ // 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 */ - /** - * @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 ejected for a quorum `quorumNumber` at array offset `index`. + * @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 + /* + * @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; + 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..9cd26302 100644 --- a/src/interfaces/IIndexRegistry.sol +++ b/src/interfaces/IIndexRegistry.sol @@ -1,55 +1,83 @@ // 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; } +} - /** +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 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): + * @param operatorId The unique identifier of the operator. + * @param quorumNumbers The quorum numbers to register for. + * @return An array containing 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: * 1) `quorumNumbers` has no duplicates * 2) `quorumNumbers.length` != 0 * 3) `quorumNumbers` is ordered in ascending order @@ -60,12 +88,12 @@ interface IIndexRegistry is IRegistry, IIndexRegistryErrors { 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): + * @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 @@ -74,46 +102,77 @@ interface IIndexRegistry is IRegistry, IIndexRegistryErrors { */ 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 2f6fe5fe..4c9397dc 100644 --- a/src/interfaces/IRegistryCoordinator.sol +++ b/src/interfaces/IRegistryCoordinator.sol @@ -1,73 +1,121 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; +import { + ISlashingRegistryCoordinator, + ISlashingRegistryCoordinatorErrors, + ISlashingRegistryCoordinatorEvents, + ISlashingRegistryCoordinatorTypes +} from "./ISlashingRegistryCoordinator.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; -import {IBLSApkRegistry} from "./IBLSApkRegistry.sol"; -import {ISlashingRegistryCoordinator} from "./ISlashingRegistryCoordinator.sol"; +import {IBLSApkRegistryTypes} from "./IBLSApkRegistry.sol"; +import {IServiceManager} from "./IServiceManager.sol"; -interface IRegistryCoordinator { - /// Emits when operator sets mode is enabled +interface IRegistryCoordinatorErrors is ISlashingRegistryCoordinatorErrors { + /// @notice Thrown when operator sets mode is already enabled. + error OperatorSetsAlreadyEnabled(); + /// @notice Thrown when a quorum is an operator set quorum. + error OperatorSetQuorum(); + /// @notice Thrown when M2 quorums are already disabled. + error M2QuorumsAlreadyDisabled(); +} + +interface IRegistryCoordinatorTypes is ISlashingRegistryCoordinatorTypes {} + +interface IRegistryCoordinatorEvents is + ISlashingRegistryCoordinatorEvents, + IRegistryCoordinatorTypes +{ + /** + * @notice Emitted when operator sets mode is enabled. + * @dev Emitted in enableOperatorSets(). + */ event OperatorSetsEnabled(); - /// Emits when M2 quorums are disabled + + /** + * @notice Emitted when M2 quorums are disabled. + * @dev Emitted in disableM2QuorumRegistration(). + */ event M2QuorumsDisabled(); +} + +interface IRegistryCoordinator is + IRegistryCoordinatorErrors, + IRegistryCoordinatorEvents, + ISlashingRegistryCoordinator +{ + /** + * @notice Reference to the ServiceManager contract. + * @return The ServiceManager contract interface. + * @dev This is only relevant for Pre-Slashing AVSs + */ + function serviceManager() external view returns (IServiceManager); + + /// ACTIONS /** - * @notice Registers msg.sender as an operator for one or more quorums. If any quorum exceeds its maximum + * @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 + * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for AVSDirectory. + * @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. + * @dev This function registers operators to the AVSDirectory using the M2-registration pathway. */ function registerOperator( bytes memory quorumNumbers, string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, + IBLSApkRegistryTypes.PubkeyRegistrationParams memory params, ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature ) external; /** - * @notice Registers msg.sender as an operator for one or more quorums. If any quorum reaches its maximum operator + * @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 params contains the G1 & G2 public keys of the operator, and a signature proving their ownership + * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for AVSDirectory. + * @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 + * 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. + * @dev This function registers operators to the AVSDirectory using the M2-registration pathway. */ function registerOperatorWithChurn( bytes calldata quorumNumbers, string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams, + 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 - * @param quorumNumbers is an ordered byte array containing the quorum numbers being deregistered from + * @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. + * @dev This function deregisters operators from the AVSDirectory using the M2-registration pathway. */ function deregisterOperator( bytes memory quorumNumbers ) external; /** - * @notice Enables operator sets mode. This is by default initialized to set `operatorSetsEnabled` to True. - * So this is only meant to be called for existing AVSs that have a existing quorums and a previously deployed - * version of middleware contracts. - * @dev This is only callable by the owner of the RegistryCoordinator + * @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 Disables registration to M2 quorums. This is only callable by the owner of the RegistryCoordinator. - * @dev This is only callable if `operatorSetsEnabled` is True. + * @notice Disables M2 quorum registration for the AVS. Once disabled, this cannot be enabled. + * @dev When disabled, all registrations to M2 quorums will revert. Deregistrations are still possible. */ function disableM2QuorumRegistration() external; } diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index bfb522af..a93f03f0 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -13,93 +13,89 @@ 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); +} +interface IServiceManager is IServiceManagerUI, IServiceManagerErrors, IServiceManagerEvents { /** - * @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 + * @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 + * 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 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 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..a506256b 100644 --- a/src/interfaces/IServiceManagerUI.sol +++ b/src/interfaces/IServiceManagerUI.sol @@ -10,7 +10,9 @@ import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISi */ interface IServiceManagerUI { /** - * Metadata should follow the format outlined by this example. + * @notice Updates the metadata URI for the AVS, + * @param metadataURI is the metadata URI for the AVS. + * @dev Metadata should follow the format outlined by this example. * { * "name": "EigenLabs AVS 1", * "website": "https://www.eigenlayer.xyz/", @@ -18,15 +20,13 @@ interface IServiceManagerUI { * "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 + * @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. */ @@ -36,7 +36,7 @@ interface IServiceManagerUI { ) external; /** - * @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator deregistration from the AVS + * @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( @@ -44,24 +44,26 @@ interface IServiceManagerUI { ) 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 + * @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 + * 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 + * @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 + * The off-chain service should do that validation separately. */ function getRestakeableStrategies() external view returns (address[] memory); - /// @notice Returns the EigenLayer AVSDirectory contract. + /** + * @notice Returns the EigenLayer AVSDirectory contract. + */ function avsDirectory() external view returns (address); } diff --git a/src/interfaces/ISlasher.sol b/src/interfaces/ISlasher.sol index b00fd65a..fe388afb 100644 --- a/src/interfaces/ISlasher.sol +++ b/src/interfaces/ISlasher.sol @@ -5,42 +5,30 @@ 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 +36,12 @@ 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 +49,44 @@ 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/ISlashingRegistryCoordinator.sol b/src/interfaces/ISlashingRegistryCoordinator.sol index 2a8dd58d..70b74af8 100644 --- a/src/interfaces/ISlashingRegistryCoordinator.sol +++ b/src/interfaces/ISlashingRegistryCoordinator.sol @@ -1,178 +1,526 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {IServiceManager} from "./IServiceManager.sol"; import {IBLSApkRegistry} from "./IBLSApkRegistry.sol"; import {IStakeRegistry} from "./IStakeRegistry.sol"; import {IIndexRegistry} from "./IIndexRegistry.sol"; import {BN254} from "../libraries/BN254.sol"; +import {IAllocationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IBLSApkRegistry} from "./IBLSApkRegistry.sol"; +import {IStakeRegistry, IStakeRegistryTypes} from "./IStakeRegistry.sol"; +import {IIndexRegistry} from "./IIndexRegistry.sol"; +import {BN254} from "../libraries/BN254.sol"; +import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol"; -interface IRegistryCoordinatorErrors { +interface ISlashingRegistryCoordinatorErrors { + /// @notice Thrown when array lengths in input parameters don't match. error InputLengthMismatch(); - error OperatorSetsAlreadyEnabled(); - error OperatorSetsNotEnabled(); - error M2QuorumsAlreadyDisabled(); + /// @notice Thrown when an invalid registration type is provided. + error InvalidRegistrationType(); + /// @notice Thrown when non-allocation manager calls restricted function. error OnlyAllocationManager(); + /// @notice Thrown when non-ejector calls restricted function. error OnlyEjector(); + /// @notice Thrown when operating on a non-existent quorum. error QuorumDoesNotExist(); + /// @notice Thrown when registering/deregistering with empty bitmap. error BitmapEmpty(); + /// @notice Thrown when registering for already registered quorums. error AlreadyRegisteredForQuorums(); + /// @notice Thrown when registering before ejection cooldown expires. error CannotReregisterYet(); + /// @notice Thrown when unregistered operator attempts restricted operation. error NotRegistered(); + /// @notice Thrown when operator attempts self-churn. error CannotChurnSelf(); + /// @notice Thrown when operator count doesn't match quorum requirements. error QuorumOperatorCountMismatch(); + /// @notice Thrown when operator has insufficient stake for churn. error InsufficientStakeForChurn(); + /// @notice Thrown when attempting to kick operator above stake threshold. error CannotKickOperatorAboveThreshold(); + /// @notice Thrown when updating to zero bitmap. error BitmapCannotBeZero(); + /// @notice Thrown when deregistering from unregistered quorum. error NotRegisteredForQuorum(); - error MaxQuorumsReached(); - error SaltAlreadyUsed(); - 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(); - error InvalidRegistrationType(); + /// @notice Thrown when maximum quorum count is reached. + error MaxQuorumsReached(); + /// @notice Thrown when operator set operations are attempted while not enabled. + error OperatorSetsNotEnabled(); } -/** - * @title Interface for a contract that coordinates between various registries for an AVS. - * @author Layr Labs, Inc. - */ -interface ISlashingRegistryCoordinator 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); +interface ISlashingRegistryCoordinatorTypes { + /// @notice Core data structure for tracking operator information. + /// @dev Links an operator's unique identifier with their current registration status. + /// @param operatorId Unique identifier for the operator, typically derived from their BLS public key. + /// @param status Current registration state of the operator in the system. + struct OperatorInfo { + bytes32 operatorId; + OperatorStatus status; + } - event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); + /// @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; + } - event EjectorUpdated(address prevEjector, address newEjector); + /// @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 emitted when all the operators for a quorum are updated at once - event QuorumBlockNumberUpdated(uint8 indexed quorumNumber, uint256 blocknumber); + /// @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; + } - // DATA STRUCTURES + /// @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 } + /** + * @notice Enum representing the type of operator registration. + * @custom:enum NORMAL Represents a normal operator registration. + * @custom:enum CHURN Represents an operator registration during a churn event. + */ enum RegistrationType { NORMAL, CHURN } - // STRUCTS - /** - * @notice Data structure for storing info on operators + * @notice Data structure for storing the results of a registerOperator call. + * @dev Contains arrays storing per-quorum information about operator counts and stakes. + * @param numOperatorsPerQuorum For each quorum the operator registered for, stores the number of operators registered. + * @param operatorStakes For each quorum the operator registered for, stores the stake of the operator in the quorum. + * @param totalStakes For each quorum the operator registered for, stores the total stake of the quorum. */ - struct 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; + struct RegisterResults { + uint32[] numOperatorsPerQuorum; + uint96[] operatorStakes; + uint96[] totalStakes; } +} +interface ISlashingRegistryCoordinatorEvents is ISlashingRegistryCoordinatorTypes { /** - * @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 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). */ - struct QuorumBitmapUpdate { - uint32 updateBlockNumber; - uint32 nextUpdateBlockNumber; - uint192 quorumBitmap; - } + event OperatorRegistered(address indexed operator, bytes32 indexed operatorId); /** - * @notice Data structure for storing the results of a registerOperator call - * @dev For each quorum the operator registered for, numOperatorsPerQuorum is the number of operators registered - * @dev For each quorum the operator registered for, operatorStakes is the stake of the operator in the quorum - * @dev For each quorum the operator registered for, totalStakes is the total stake of the quorum + * @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). */ - struct RegisterResults { - uint32[] numOperatorsPerQuorum; - uint96[] operatorStakes; - uint96[] totalStakes; - } + event OperatorDeregistered(address indexed operator, bytes32 indexed operatorId); /** - * @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 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. */ - struct OperatorSetParam { - uint32 maxOperatorCount; - uint16 kickBIPsOfOperatorStake; - uint16 kickBIPsOfTotalStake; - } + event OperatorSetParamsUpdated(uint8 indexed quorumNumber, OperatorSetParam operatorSetParams); /** - * @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 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. */ - struct OperatorKickParam { - uint8 quorumNumber; - address operator; - } + event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); - /// @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 + /** + * @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 ISlashingRegistryCoordinator is + IAVSRegistrar, + ISlashingRegistryCoordinatorErrors, + ISlashingRegistryCoordinatorEvents +{ + /// IMMUTABLES & CONSTANTS + + /** + * @notice EIP-712 typehash for operator churn approval signatures. + * @return The typehash constant. + */ + function OPERATOR_CHURN_APPROVAL_TYPEHASH() external view returns (bytes32); + + /** + * @notice EIP-712 typehash for pubkey registration signatures. + * @return The typehash constant. + */ + function PUBKEY_REGISTRATION_TYPEHASH() external view returns (bytes32); + + /** + * @notice Reference to the BLSApkRegistry contract. + * @return The BLSApkRegistry contract interface. + */ function blsApkRegistry() external view returns (IBLSApkRegistry); - /// @notice 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 + * @notice Reference to the AllocationManager contract. + * @return The AllocationManager contract interface. + * @dev This is only relevant for Slashing AVSs */ - function ejectOperator(address operator, bytes calldata quorumNumbers) external; + function allocationManager() external view returns (IAllocationManager); + + /// STORAGE - /// @notice Returns the number of quorums the registry coordinator has created + /** + * @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 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); + + /** + * @notice Whether operator sets mode is enabled. + * @return True if operator sets mode is enabled, false otherwise. + */ + function operatorSetsEnabled() external view returns (bool); + + /// ACTIONS + + /** + * @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. + * @dev This function implements the Slashing registration pathway specified by the IAVSRegistrar interface. + */ + 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. + * @dev This function implements the Slashing deregistration pathway specified by the IAVSRegistrar interface. + */ + 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 (OperatorStatus); - /// @notice Returns the indices of the quorumBitmaps for the provided `operatorIds` at the given `blockNumber` + /** + * @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, @@ -180,60 +528,79 @@ interface ISlashingRegistryCoordinator is IRegistryCoordinatorErrors { 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 operator sets mode is enabled - function operatorSetsEnabled() 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 + * @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); /** - * @notice The account identifier for this AVS (used for UAM integration in EigenLayer) - * @dev NOTE: Updating this value will break existing OperatorSets and UAM integration. - * This value should only be set once. + * @notice Returns the account identifier for this AVS (used for UAM integration in EigenLayer) + * @dev NOTE: Updating this value will break existing OperatorSets and UAM integration. This value should only be set once. + * @return The account identifier address */ function accountIdentifier() external view returns (address); } 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 66108a75..b7e74644 100644 --- a/src/interfaces/IStakeRegistry.sol +++ b/src/interfaces/IStakeRegistry.sol @@ -5,13 +5,7 @@ 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 error OnlySlashingRegistryCoordinator(); @@ -19,143 +13,233 @@ interface IStakeRegistryErrors { error OnlySlashingRegistryCoordinatorOwner(); /// @dev Thrown when the stake is below the minimum required 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 +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 ); +} + +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 The operator's current stake for each quorum, and the total stake for each quorum - * @dev access restricted to the RegistryCoordinator + * @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 + * 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); + ) 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 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 + * 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 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. */ - /// @notice Initialize a new quorum and push its first history update 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, @@ -163,31 +247,64 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { 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]`. + /** + * @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, @@ -195,47 +312,66 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) external view returns (uint96); /** - * @notice Returns the entire `operatorIdToStakeHistory[operatorId][quorumNumber]` array. + * @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]`. + * @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( @@ -245,8 +381,11 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) 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, @@ -254,15 +393,14 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) 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. + * @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 the BLSSignatureChecker to get past stakes of signing operators + * @dev Used by the BLSSignatureChecker to get past stakes of signing operators. */ function getStakeAtBlockNumberAndIndex( uint8 quorumNumber, @@ -272,14 +410,13 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) 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. + * @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 the BLSSignatureChecker to get past stakes of signing operators + * @dev Used by the BLSSignatureChecker to get past stakes of signing operators. */ function getTotalStakeAtBlockNumberFromIndex( uint8 quorumNumber, @@ -288,15 +425,24 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) 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, @@ -304,25 +450,12 @@ interface IStakeRegistry is IRegistry, IStakeRegistryErrors { ) external view returns (uint96); /** - * @notice Returns the stake weight from the latest entry in `_totalStakeHistory` for quorum `quorumNumber`. + * @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/BN254.sol b/src/libraries/BN254.sol index 7a167efc..df4b8248 100644 --- a/src/libraries/BN254.sol +++ b/src/libraries/BN254.sol @@ -30,10 +30,10 @@ pragma solidity ^0.8.27; library BN254 { // modulus for the underlying field F_p of the elliptic curve uint256 internal constant FP_MODULUS = - 21_888_242_871_839_275_222_246_405_745_257_275_088_696_311_157_297_823_662_689_037_894_645_226_208_583; + 21888242871839275222246405745257275088696311157297823662689037894645226208583; // modulus for the underlying field F_r of the elliptic curve uint256 internal constant FR_MODULUS = - 21_888_242_871_839_275_222_246_405_745_257_275_088_548_364_400_416_034_343_698_204_186_575_808_495_617; + 21888242871839275222246405745257275088548364400416034343698204186575808495617; struct G1Point { uint256 X; @@ -64,13 +64,13 @@ library BN254 { // generator of group G2 /// @dev Generator point in F_q2 is of the form: (x0 + ix1, y0 + iy1). uint256 internal constant G2x1 = - 11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634; + 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 internal constant G2x0 = - 10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781; + 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 internal constant G2y1 = - 4_082_367_875_863_433_681_332_203_403_145_435_568_316_851_327_593_401_208_105_741_076_214_120_093_531; + 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 internal constant G2y0 = - 8_495_653_923_123_431_417_604_973_247_489_272_438_418_190_587_263_600_148_770_280_649_306_958_101_930; + 8495653923123431417604973247489272438418190587263600148770280649306958101930; /// @notice returns the G2 generator /// @dev mind the ordering of the 1s and 0s! @@ -84,13 +84,13 @@ library BN254 { // negation of the generator of group G2 /// @dev Generator point in F_q2 is of the form: (x0 + ix1, y0 + iy1). uint256 internal constant nG2x1 = - 11_559_732_032_986_387_107_991_004_021_392_285_783_925_812_861_821_192_530_917_403_151_452_391_805_634; + 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 internal constant nG2x0 = - 10_857_046_999_023_057_135_944_570_762_232_829_481_370_756_359_578_518_086_990_519_993_285_655_852_781; + 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 internal constant nG2y1 = - 17_805_874_995_975_841_540_914_202_342_111_839_520_379_459_829_704_422_454_583_296_818_431_106_115_052; + 17805874995975841540914202342111839520379459829704422454583296818431106115052; uint256 internal constant nG2y0 = - 13_392_588_948_715_843_804_641_432_497_768_002_650_278_120_570_034_223_513_918_757_245_338_268_106_653; + 13392588948715843804641432497768002650278120570034223513918757245338268106653; function negGeneratorG2() internal pure returns (G2Point memory) { return G2Point([nG2x1, nG2x0], [nG2y1, nG2y0]); diff --git a/src/libraries/QuorumBitmapHistoryLib.sol b/src/libraries/QuorumBitmapHistoryLib.sol index 677c8678..d709b035 100644 --- a/src/libraries/QuorumBitmapHistoryLib.sol +++ b/src/libraries/QuorumBitmapHistoryLib.sol @@ -1,7 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.27; -import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol"; +import { + ISlashingRegistryCoordinator, + ISlashingRegistryCoordinatorTypes +} from "../interfaces/ISlashingRegistryCoordinator.sol"; /// @title QuorumBitmapHistoryLib /// @notice This library operates on the _operatorBitmapHistory in the RegistryCoordinator @@ -119,7 +122,7 @@ library QuorumBitmapHistoryLib { if (historyLength == 0) { // No prior bitmap history - push our first entry self[operatorId].push( - ISlashingRegistryCoordinator.QuorumBitmapUpdate({ + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0, quorumBitmap: newBitmap @@ -139,7 +142,7 @@ library QuorumBitmapHistoryLib { } else { lastUpdate.nextUpdateBlockNumber = uint32(block.number); self[operatorId].push( - ISlashingRegistryCoordinator.QuorumBitmapUpdate({ + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0, quorumBitmap: newBitmap diff --git a/src/unaudited/ECDSAServiceManagerBase.sol b/src/unaudited/ECDSAServiceManagerBase.sol index 57a4067e..2a978b0b 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..8d9d69d8 100644 --- a/src/unaudited/ECDSAStakeRegistryStorage.sol +++ b/src/unaudited/ECDSAStakeRegistryStorage.sol @@ -6,23 +6,21 @@ 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; /// @dev The total amount of multipliers to weigh stakes - uint256 internal constant BPS = 10_000; + uint256 internal constant BPS = 10000; /// @notice The size of the current operator set 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 78d3ca72..44283d9c 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"; import {ISlashingRegistryCoordinator} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; contract BLSApkRegistryFFITests is G2Operations { @@ -16,7 +16,7 @@ contract BLSApkRegistryFFITests is G2Operations { ISlashingRegistryCoordinator 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/harnesses/RegistryCoordinatorHarness.t.sol b/test/harnesses/RegistryCoordinatorHarness.t.sol index 8d6e6bc4..7adf32dc 100644 --- a/test/harnesses/RegistryCoordinatorHarness.t.sol +++ b/test/harnesses/RegistryCoordinatorHarness.t.sol @@ -67,11 +67,15 @@ contract RegistryCoordinatorHarness is RegistryCoordinator, Test { _updateOperatorBitmap(operatorId, quorumBitmap); } - function setOperatorSetsEnabled(bool enabled) external { + function setOperatorSetsEnabled( + bool enabled + ) external { operatorSetsEnabled = enabled; } - function setM2QuorumsDisabled(bool disabled) external { + function setM2QuorumsDisabled( + bool disabled + ) external { m2QuorumsDisabled = disabled; } } diff --git a/test/harnesses/StakeRegistryHarness.sol b/test/harnesses/StakeRegistryHarness.sol index 3fe3a187..2a205541 100644 --- a/test/harnesses/StakeRegistryHarness.sol +++ b/test/harnesses/StakeRegistryHarness.sol @@ -10,8 +10,7 @@ contract StakeRegistryHarness is StakeRegistry { IDelegationManager _delegationManager, IAVSDirectory _avsDirectory, IAllocationManager _allocationManager - ) StakeRegistry(_registryCoordinator, _delegationManager, _avsDirectory, _allocationManager) { - } + ) StakeRegistry(_registryCoordinator, _delegationManager, _avsDirectory, _allocationManager) {} function recordOperatorStakeUpdate( bytes32 operatorId, diff --git a/test/integration/CoreRegistration.t.sol b/test/integration/CoreRegistration.t.sol index d3bffe8d..bd1718c6 100644 --- a/test/integration/CoreRegistration.t.sol +++ b/test/integration/CoreRegistration.t.sol @@ -57,7 +57,7 @@ contract Test_CoreRegistration is MockAVSDeployer { address(this), pauserRegistry, 0, // 0 is initialPausedStatus - 50_400, // Initial withdrawal delay blocks + 50400, // Initial withdrawal delay blocks initializeStrategiesToSetDelayBlocks, initializeWithdrawalDelayBlocks ) diff --git a/test/integration/IntegrationBase.t.sol b/test/integration/IntegrationBase.t.sol index 388535c6..180edd11 100644 --- a/test/integration/IntegrationBase.t.sol +++ b/test/integration/IntegrationBase.t.sol @@ -29,22 +29,26 @@ abstract contract IntegrationBase is IntegrationConfig { /// @dev Also checks that the user has NEVER_REGISTERED status function assert_HasNoOperatorInfo(User user, string memory err) internal { - ISlashingRegistryCoordinator.OperatorInfo memory info = _getOperatorInfo(user); + ISlashingRegistryCoordinatorTypes.OperatorInfo memory info = _getOperatorInfo(user); assertEq(info.operatorId, bytes32(0), err); - assertTrue(info.status == ISlashingRegistryCoordinator.OperatorStatus.NEVER_REGISTERED, err); + assertTrue( + info.status == ISlashingRegistryCoordinatorTypes.OperatorStatus.NEVER_REGISTERED, err + ); } function assert_HasRegisteredStatus(User user, string memory err) internal { - ISlashingRegistryCoordinator.OperatorStatus status = registryCoordinator.getOperatorStatus(address(user)); + ISlashingRegistryCoordinatorTypes.OperatorStatus status = + registryCoordinator.getOperatorStatus(address(user)); - assertTrue(status == ISlashingRegistryCoordinator.OperatorStatus.REGISTERED, err); + assertTrue(status == ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED, err); } function assert_HasDeregisteredStatus(User user, string memory err) internal { - ISlashingRegistryCoordinator.OperatorStatus status = registryCoordinator.getOperatorStatus(address(user)); + ISlashingRegistryCoordinatorTypes.OperatorStatus status = + registryCoordinator.getOperatorStatus(address(user)); - assertTrue(status == ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED, err); + assertTrue(status == ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED, err); } function assert_EmptyQuorumBitmap(User user, string memory err) internal { @@ -241,8 +245,8 @@ abstract contract IntegrationBase is IntegrationConfig { } function assert_Snap_Unchanged_OperatorInfo(User user, string memory err) internal { - ISlashingRegistryCoordinator.OperatorInfo memory curInfo = _getOperatorInfo(user); - ISlashingRegistryCoordinator.OperatorInfo memory prevInfo = _getPrevOperatorInfo(user); + ISlashingRegistryCoordinatorTypes.OperatorInfo memory curInfo = _getOperatorInfo(user); + ISlashingRegistryCoordinatorTypes.OperatorInfo memory prevInfo = _getPrevOperatorInfo(user); assertEq(prevInfo.operatorId, curInfo.operatorId, err); assertTrue(prevInfo.status == curInfo.status, err); @@ -862,11 +866,15 @@ abstract contract IntegrationBase is IntegrationConfig { /// RegistryCoordinator: - function _getOperatorInfo(User user) internal view returns (ISlashingRegistryCoordinator.OperatorInfo memory) { + function _getOperatorInfo( + User user + ) internal view returns (ISlashingRegistryCoordinatorTypes.OperatorInfo memory) { return registryCoordinator.getOperator(address(user)); } - function _getPrevOperatorInfo(User user) internal timewarp() returns (ISlashingRegistryCoordinator.OperatorInfo memory) { + function _getPrevOperatorInfo( + User user + ) internal timewarp returns (ISlashingRegistryCoordinatorTypes.OperatorInfo memory) { return _getOperatorInfo(user); } diff --git a/test/integration/IntegrationConfig.t.sol b/test/integration/IntegrationConfig.t.sol index 4581372f..92c394bb 100644 --- a/test/integration/IntegrationConfig.t.sol +++ b/test/integration/IntegrationConfig.t.sol @@ -6,16 +6,18 @@ import "forge-std/Test.sol"; import "test/integration/IntegrationDeployer.t.sol"; import "test/ffi/util/G2Operations.sol"; import "test/integration/utils/BitmapStrings.t.sol"; +import {ISlashingRegistryCoordinatorTypes} from + "../../src/interfaces/ISlashingRegistryCoordinator.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 /// This is a low number because each operator receives its own BLS keypair, which /// is very slow to generate. uint32 constant MAX_OPERATOR_COUNT = 5; - uint16 constant KICK_BIPS_OPERATOR_STAKE = 15_000; + uint16 constant KICK_BIPS_OPERATOR_STAKE = 15000; uint16 constant KICK_BIPS_TOTAL_STAKE = 150; /// Other: @@ -26,7 +28,7 @@ contract Constants { uint256 constant MAX_QUORUM_COUNT = 192; // From RegistryCoordinator.MAX_QUORUM_COUNT - uint16 internal constant BIPS_DENOMINATOR = 10_000; + uint16 internal constant BIPS_DENOMINATOR = 10000; } contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { @@ -73,7 +75,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 +95,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 +160,8 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { emit log_named_uint("_configRand: number of quorums being initialized", quorumCount); // Default OperatorSetParams for all quorums - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSet = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSet = + ISlashingRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: MAX_OPERATOR_COUNT, kickBIPsOfOperatorStake: KICK_BIPS_OPERATOR_STAKE, kickBIPsOfTotalStake: KICK_BIPS_TOTAL_STAKE @@ -166,7 +169,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); @@ -232,7 +235,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; @@ -317,8 +321,8 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { for (uint256 i = 0; i < churnQuorums.length; i++) { uint8 quorum = uint8(churnQuorums[i]); - ISlashingRegistryCoordinator.OperatorSetParam memory params - = registryCoordinator.getOperatorSetParams(quorum); + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory params = + registryCoordinator.getOperatorSetParams(quorum); // Sanity check - make sure we're at the operator cap uint32 curNumOperators = indexRegistry.totalOperatorsForQuorum(quorum); @@ -364,7 +368,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { /// From RegistryCoordinator._individualKickThreshold function _individualKickThreshold( uint96 operatorStake, - ISlashingRegistryCoordinator.OperatorSetParam memory setParams + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory setParams ) internal pure returns (uint96) { return operatorStake * setParams.kickBIPsOfOperatorStake / BIPS_DENOMINATOR; } @@ -372,7 +376,7 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { /// From RegistryCoordinator._totalKickThreshold function _totalKickThreshold( uint96 totalStake, - ISlashingRegistryCoordinator.OperatorSetParam memory setParams + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory setParams ) internal pure returns (uint96) { return totalStake * setParams.kickBIPsOfTotalStake / BIPS_DENOMINATOR; } @@ -421,7 +425,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) { @@ -431,7 +435,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); @@ -527,7 +531,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; @@ -547,11 +551,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 }); @@ -564,8 +568,10 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { * @dev Uses _randFillType to determine how many operators to register for a quorum initially * @return The number of operators to register */ - function _randInitialOperators(ISlashingRegistryCoordinator.OperatorSetParam memory operatorSet) private returns (uint) { - uint fillTypeFlag = _randValue(fillTypeFlags); + function _randInitialOperators( + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSet + ) private returns (uint256) { + uint256 fillTypeFlag = _randValue(fillTypeFlags); if (fillTypeFlag == EMPTY) { return 0; diff --git a/test/integration/IntegrationDeployer.t.sol b/test/integration/IntegrationDeployer.t.sol index 323c1cc8..508fb869 100644 --- a/test/integration/IntegrationDeployer.t.sol +++ b/test/integration/IntegrationDeployer.t.sol @@ -107,9 +107,9 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { /// @notice Upper bound start range is ~1 month into the future, multiple of CALCULATION_INTERVAL_SECONDS uint32 MAX_FUTURE_LENGTH = 28 days; /// @notice absolute min timestamp that a rewards can start at - uint32 GENESIS_REWARDS_TIMESTAMP = 1_712_188_800; + uint32 GENESIS_REWARDS_TIMESTAMP = 1712188800; /// @notice Equivalent to 100%, but in basis points. - uint16 internal constant ONE_HUNDRED_IN_BIPS = 10_000; + uint16 internal constant ONE_HUNDRED_IN_BIPS = 10000; uint32 defaultOperatorSplitBips = 1000; /// @notice Delay in timestamp before a posted root can be claimed against @@ -339,7 +339,10 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { cheats.stopPrank(); StakeRegistry stakeRegistryImplementation = new StakeRegistry( - ISlashingRegistryCoordinator(registryCoordinator), IDelegationManager(delegationManager), IAVSDirectory(avsDirectory), allocationManager + ISlashingRegistryCoordinator(registryCoordinator), + IDelegationManager(delegationManager), + IAVSDirectory(avsDirectory), + allocationManager ); BLSApkRegistry blsApkRegistryImplementation = new BLSApkRegistry(ISlashingRegistryCoordinator(registryCoordinator)); @@ -379,7 +382,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( @@ -399,7 +403,11 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { churnApprover, ejector, 0, /*initialPausedStatus*/ - address(serviceManager) // _accountIdentifier + new IRegistryCoordinator.OperatorSetParam[](0), + new uint96[](0), + new IStakeRegistryTypes.StrategyParams[][](0), + quorumStakeTypes, + slashableStakeQuorumLookAheadPeriods ) ); @@ -445,26 +453,32 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { /// @notice Overwrite RegistryCoordinator.operatorSetsEnabled to the specified value. /// This is to enable testing of RegistryCoordinator in non-operator set mode. - function _setOperatorSetsEnabled(bool operatorSetsEnabled) internal { + function _setOperatorSetsEnabled( + bool operatorSetsEnabled + ) internal { // 1. First read the current value of the entire slot // which holds operatorSetsEnabled, m2QuorumsDisabled, and accountIdentifier bytes32 currentSlot = cheats.load(address(registryCoordinator), bytes32(uint256(161))); // 2. Clear only the first byte (operatorSetsEnabled) while keeping the rest - bytes32 newSlot = (currentSlot & ~bytes32(uint256(0xff))) | bytes32(uint256(operatorSetsEnabled ? 0x01 : 0x00)); + bytes32 newSlot = (currentSlot & ~bytes32(uint256(0xff))) + | bytes32(uint256(operatorSetsEnabled ? 0x01 : 0x00)); // 3. Store the modified slot cheats.store(address(registryCoordinator), bytes32(uint256(161)), newSlot); } /// @notice Overwrite RegistryCoordinator.m2QuorumsDisabled to the specified value. - function _setM2QuorumsDisabled(bool m2QuorumsDisabled) internal { + function _setM2QuorumsDisabled( + bool m2QuorumsDisabled + ) internal { // 1. First read the current value of the entire slot // which holds operatorSetsEnabled, m2QuorumsDisabled, and accountIdentifier bytes32 currentSlot = cheats.load(address(registryCoordinator), bytes32(uint256(161))); // 2. Clear only the second byte (m2QuorumsDisabled) while keeping the rest - bytes32 newSlot = (currentSlot & ~bytes32(uint256(0xff) << 8)) | bytes32(uint256(m2QuorumsDisabled ? 0x01 : 0x00) << 8); + bytes32 newSlot = (currentSlot & ~bytes32(uint256(0xff) << 8)) + | bytes32(uint256(m2QuorumsDisabled ? 0x01 : 0x00) << 8); // 3. Store the modified slot cheats.store(address(registryCoordinator), bytes32(uint256(161)), newSlot); diff --git a/test/integration/User.t.sol b/test/integration/User.t.sol index 42e8740e..8a1a9b61 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); @@ -160,8 +161,8 @@ contract User is Test { bytes memory allQuorums = churnBitmap.plus(standardBitmap).bitmapToBytesArray(); - ISlashingRegistryCoordinator.OperatorKickParam[] memory kickParams - = new ISlashingRegistryCoordinator.OperatorKickParam[](allQuorums.length); + ISlashingRegistryCoordinator.OperatorKickParam[] memory kickParams = + new ISlashingRegistryCoordinator.OperatorKickParam[](allQuorums.length); // this constructs OperatorKickParam[] in ascending quorum order // (yikes) @@ -169,19 +170,21 @@ contract User is Test { uint256 stdIdx; while (churnIdx + stdIdx < allQuorums.length) { if (churnIdx == churnQuorums.length) { - kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinator.OperatorKickParam({ + kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: 0, operator: address(0) }); stdIdx++; - } else if (stdIdx == standardQuorums.length || churnQuorums[churnIdx] < standardQuorums[stdIdx]) { - kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinator.OperatorKickParam({ + } else if ( + stdIdx == standardQuorums.length || churnQuorums[churnIdx] < standardQuorums[stdIdx] + ) { + kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: uint8(churnQuorums[churnIdx]), operator: address(churnTargets[churnIdx]) }); churnIdx++; } else if (standardQuorums[stdIdx] < churnQuorums[churnIdx]) { - kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinator.OperatorKickParam({ + kickParams[churnIdx + stdIdx] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: 0, operator: address(0) }); @@ -386,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/AVSRegistrarMock.sol b/test/mocks/AVSRegistrarMock.sol index 2684275c..9a61b26e 100644 --- a/test/mocks/AVSRegistrarMock.sol +++ b/test/mocks/AVSRegistrarMock.sol @@ -3,7 +3,6 @@ pragma solidity ^0.8.27; import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSRegistrar.sol"; - contract AVSRegistrarMock is IAVSRegistrar { function registerOperator( address operator, diff --git a/test/mocks/DelegationMock.sol b/test/mocks/DelegationMock.sol index ff04b970..11bce967 100644 --- a/test/mocks/DelegationMock.sol +++ b/test/mocks/DelegationMock.sol @@ -283,6 +283,6 @@ contract DelegationMock is DelegationIntermediate { } function minWithdrawalDelayBlocks() external view override returns (uint32) { - return 10_000; + return 10000; } } diff --git a/test/mocks/ECDSAServiceManagerMock.sol b/test/mocks/ECDSAServiceManagerMock.sol index d77fc961..07a263cf 100644 --- a/test/mocks/ECDSAServiceManagerMock.sol +++ b/test/mocks/ECDSAServiceManagerMock.sol @@ -37,7 +37,10 @@ contract ECDSAServiceManagerMock is ECDSAServiceManagerBase { address pendingAdmin ) external {} - function deregisterOperatorFromOperatorSets(address operator, uint32[] memory operatorSetIds) external {} + function deregisterOperatorFromOperatorSets( + address operator, + uint32[] memory operatorSetIds + ) external {} function removeAdmin( address admin diff --git a/test/mocks/RegistryCoordinatorMock.sol b/test/mocks/RegistryCoordinatorMock.sol index 533e14ef..78c98660 100644 --- a/test/mocks/RegistryCoordinatorMock.sol +++ b/test/mocks/RegistryCoordinatorMock.sol @@ -3,130 +3,162 @@ pragma solidity ^0.8.27; import "../../src/interfaces/IRegistryCoordinator.sol"; import "../../src/interfaces/ISlashingRegistryCoordinator.sol"; - - -contract RegistryCoordinatorMock is ISlashingRegistryCoordinator, 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 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` - function getOperatorStatus(address operator) external view returns (OperatorStatus){} - - /// @notice Returns task number from when `operator` has been registered. - function getFromTaskNumberForOperator( + ) external view virtual returns (address) {} + function getOperatorStatus( 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 accountIdentifier() external view returns (address) {} - - function deregisterOperator(bytes memory quorumNumbers) external {} - - function enableOperatorSets() external {} - - function registerOperator( - bytes memory quorumNumbers, - string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature - ) external {} - - function registerOperatorWithChurn( - bytes calldata quorumNumbers, - string memory socket, - IBLSApkRegistry.PubkeyRegistrationParams memory params, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams, - ISignatureUtils.SignatureWithSaltAndExpiry memory churnApproverSignature, - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature - ) external {} - - function disableM2QuorumRegistration() external {} - - function operatorSetsEnabled() external view returns (bool) {} } 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/BLSApkRegistryUnit.t.sol b/test/unit/BLSApkRegistryUnit.t.sol index 295d5cec..785811fd 100644 --- a/test/unit/BLSApkRegistryUnit.t.sol +++ b/test/unit/BLSApkRegistryUnit.t.sol @@ -66,13 +66,13 @@ contract BLSApkRegistryUnitTests is BLSMockAVSDeployer, IBLSApkRegistryEvents { //privKey*G2 pubkeyRegistrationParams.pubkeyG2.X[1] = - 19_101_821_850_089_705_274_637_533_855_249_918_363_070_101_489_527_618_151_493_230_256_975_900_223_847; + 19101821850089705274637533855249918363070101489527618151493230256975900223847; pubkeyRegistrationParams.pubkeyG2.X[0] = - 5_334_410_886_741_819_556_325_359_147_377_682_006_012_228_123_419_628_681_352_847_439_302_316_235_957; + 5334410886741819556325359147377682006012228123419628681352847439302316235957; pubkeyRegistrationParams.pubkeyG2.Y[1] = - 354_176_189_041_917_478_648_604_979_334_478_067_325_821_134_838_555_150_300_539_079_146_482_658_331; + 354176189041917478648604979334478067325821134838555150300539079146482658331; pubkeyRegistrationParams.pubkeyG2.Y[0] = - 4_185_483_097_059_047_421_902_184_823_581_361_466_320_657_066_600_218_863_748_375_739_772_335_928_910; + 4185483097059047421902184823581361466320657066600218863748375739772335928910; // Initialize 3 quorums _initializeQuorum(); diff --git a/test/unit/BLSSignatureCheckerUnit.t.sol b/test/unit/BLSSignatureCheckerUnit.t.sol index a58d6112..ef13c575 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"; @@ -128,12 +131,12 @@ contract BLSSignatureCheckerUnitTests is BLSMockAVSDeployer { assertEq( quorumStakeTotals.signedStakeForQuorum[0], - 3_000_000_000_000_000_000, + 3000000000000000000, "signedStakeForQuorum incorrect" ); assertEq( quorumStakeTotals.totalStakeForQuorum[0], - 4_000_000_000_000_000_000, + 4000000000000000000, "totalStakeForQuorum incorrect" ); } @@ -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/BitmapUtils.t.sol b/test/unit/BitmapUtils.t.sol index 1563d687..6e62f466 100644 --- a/test/unit/BitmapUtils.t.sol +++ b/test/unit/BitmapUtils.t.sol @@ -298,7 +298,7 @@ contract BitmapUtilsUnitTests_bytesArrayToBitmap is BitmapUtilsUnitTests { function test_bitmapToBytesArrayToBitmap_distributedTenEntriesBitmap() public { // 2^0+2^10+2^20+2^30+2^40+2^50+2^60+2^70+2^80+2^90 - uint256 originalBitmap = 1_239_150_146_850_664_126_585_242_625; + uint256 originalBitmap = 1239150146850664126585242625; testFuzz_bitmapToBytesArrayToBitmap(originalBitmap); } } 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..befc76c4 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,8 +22,9 @@ contract EqualWeightECDSARegistry is ECDSAStakeRegistrySetup { fixedWeightRegistry = new ECDSAStakeRegistryEqualWeight(IDelegationManager(address(mockDelegationManager))); 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 StrategyParams[](1)}); + quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10000}); fixedWeightRegistry.initialize(address(mockServiceManager), 100, quorum); fixedWeightRegistry.permitOperator(operator1); diff --git a/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol b/test/unit/ECDSAStakeRegistryPermissionedUnit.t.sol index ced14a41..7269e1ce 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,8 +23,9 @@ contract PermissionedECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { permissionedRegistry = new ECDSAStakeRegistryPermissioned(IDelegationManager(address(mockDelegationManager))); 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 StrategyParams[](1)}); + quorum.strategies[0] = StrategyParams({strategy: mockStrategy, multiplier: 10000}); permissionedRegistry.initialize(address(mockServiceManager), 100, quorum); permissionedRegistry.permitOperator(operator1); @@ -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..540f8dcc 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: 10000}); 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: 10000}); 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: 10000 + }); 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}); + StrategyParams({strategy: IStrategy(address(420)), multiplier: 10001}); 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}); @@ -387,13 +404,13 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { } function testUpdateThresholdStake_UpdateThresholdStake() public { - uint256 thresholdWeight = 10_000_000_000; + uint256 thresholdWeight = 10000000000; vm.prank(registry.owner()); registry.updateStakeThreshold(thresholdWeight); } function test_RevertsWhen_NotOwner_UpdateThresholdStake() public { - uint256 thresholdWeight = 10_000_000_000; + uint256 thresholdWeight = 10000000000; address notOwner = address(0x123); vm.prank(notOwner); vm.expectRevert("Ownable: caller is not the owner"); @@ -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)); } @@ -489,7 +506,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { (v, r, s) = vm.sign(operator2Pk, msgHash); signatures[1] = abi.encodePacked(r, s, v); - uint256 thresholdWeight = 10_000_000_000; + uint256 thresholdWeight = 10000000000; vm.prank(registry.owner()); registry.updateStakeThreshold(thresholdWeight); vm.roll(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)); } @@ -557,7 +574,7 @@ contract ECDSAStakeRegistryTest is ECDSAStakeRegistrySetup { (v, r, s) = vm.sign(operator2Pk, msgHash); signatures[1] = abi.encodePacked(r, s, v); - uint256 thresholdWeight = 10_000_000_000; + uint256 thresholdWeight = 10000000000; vm.prank(registry.owner()); registry.updateStakeThreshold(thresholdWeight); vm.roll(referenceBlock + 1); @@ -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 886a94f5..6ff658a9 100644 --- a/test/unit/EjectionManagerUnit.t.sol +++ b/test/unit/EjectionManagerUnit.t.sol @@ -3,8 +3,12 @@ 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 {ISlashingRegistryCoordinatorTypes} from "../../src/interfaces/IRegistryCoordinator.sol"; import "../utils/MockAVSDeployer.sol"; contract EjectionManagerUnitTests is MockAVSDeployer { @@ -18,7 +22,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 +30,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 }) @@ -42,7 +46,8 @@ contract EjectionManagerUnitTests is MockAVSDeployer { ) ); - ejectionManagerImplementation = new EjectionManager(registryCoordinator, stakeRegistry); + ejectionManagerImplementation = + new EjectionManager(IRegistryCoordinator(address(registryCoordinator)), stakeRegistry); address[] memory ejectors = new address[](1); ejectors[0] = ejector; @@ -80,7 +85,10 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - assertEq(uint8(registryCoordinator.getOperatorStatus(defaultOperator)), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + assertEq( + uint8(registryCoordinator.getOperatorStatus(defaultOperator)), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); for (uint8 i = 0; i < numQuorums; i++) { for (uint8 j = 0; j < operatorsToEject; j++) { @@ -92,7 +100,10 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - assertEq(uint8(registryCoordinator.getOperatorStatus(defaultOperator)), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + assertEq( + uint8(registryCoordinator.getOperatorStatus(defaultOperator)), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } function testEjectOperators_MultipleOperatorInsideRatelimit() public { @@ -110,8 +121,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -124,8 +138,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } } @@ -145,8 +162,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -159,12 +179,18 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsCanEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsCanEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } - for(uint8 i = operatorsCanEject; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = operatorsCanEject; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } } @@ -183,8 +209,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -197,8 +226,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } cheats.warp(block.timestamp + (ratelimitWindow / 2)); @@ -213,8 +245,15 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, operatorsToEject + i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8( + registryCoordinator.getOperatorStatus( + _incrementAddress(defaultOperator, operatorsToEject + i) + ) + ), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -227,8 +266,15 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, operatorsToEject + i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8( + registryCoordinator.getOperatorStatus( + _incrementAddress(defaultOperator, operatorsToEject + i) + ) + ), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } } @@ -254,8 +300,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -268,8 +317,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } } @@ -288,8 +340,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { } } - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -302,8 +357,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(registryCoordinatorOwner); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } } @@ -325,8 +383,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(defaultOperator); registryCoordinator.deregisterOperator(BitmapUtils.bitmapToBytesArray(MAX_QUORUM_BITMAP)); - for(uint8 i = 1; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.REGISTERED)); + for (uint8 i = 1; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED) + ); } for (uint8 i = 0; i < numQuorums; i++) { @@ -339,8 +400,11 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(ejector); ejectionManager.ejectOperators(operatorIds); - for(uint8 i = 0; i < operatorsToEject; i++) { - assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED)); + for (uint8 i = 0; i < operatorsToEject; i++) { + assertEq( + uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED) + ); } } @@ -348,8 +412,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 }); @@ -393,13 +457,13 @@ contract EjectionManagerUnitTests is MockAVSDeployer { cheats.prank(registryCoordinatorOwner); ejectionManager.setQuorumEjectionParams( 0, - IEjectionManager.QuorumEjectionParams({ + IEjectionManagerTypes.QuorumEjectionParams({ rateLimitWindow: 7 days, ejectableStakePercent: 9999 }) ); - stakeRegistry.recordTotalStakeUpdate(1, 2_000_000_000 * 1 ether); + stakeRegistry.recordTotalStakeUpdate(1, 2000000000 * 1 ether); ejectionManager.amountEjectableForQuorum(1); } 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 cc40349c..79a93988 100644 --- a/test/unit/OperatorStateRetrieverUnit.t.sol +++ b/test/unit/OperatorStateRetrieverUnit.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.27; import "../utils/MockAVSDeployer.sol"; import {IStakeRegistryErrors} from "../../src/interfaces/IStakeRegistry.sol"; +import {ISlashingRegistryCoordinatorTypes} from "../../src/interfaces/IRegistryCoordinator.sol"; contract OperatorStateRetrieverUnitTests is MockAVSDeployer { using BN254 for BN254.G1Point; @@ -81,17 +82,19 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer { function test_getOperatorState_revert_quorumNotCreatedAtReferenceBlockNumber() public { cheats.roll(registrationBlockNumber); - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator - .OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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 +226,19 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer { bytes32[] memory nonSignerOperatorIds = new bytes32[](1); nonSignerOperatorIds[0] = defaultOperatorId; - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator - .OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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( @@ -255,8 +260,7 @@ contract OperatorStateRetrieverUnitTests is MockAVSDeployer { uint256 quorumBitmapThree = 3; assertFalse( - registryCoordinator.operatorSetsEnabled(), - "operatorSetsEnabled should be false" + registryCoordinator.operatorSetsEnabled(), "operatorSetsEnabled should be false" ); cheats.roll(registrationBlockNumber); diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index 06a19576..a734171a 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -2,7 +2,13 @@ pragma solidity ^0.8.27; import "../utils/MockAVSDeployer.sol"; -import {ISlashingRegistryCoordinator, IRegistryCoordinatorErrors} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; +import { + ISlashingRegistryCoordinator, + ISlashingRegistryCoordinatorTypes, + ISlashingRegistryCoordinatorErrors +} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; + +import {IBLSApkRegistryTypes} from "../../src/interfaces/IBLSApkRegistry.sol"; import {QuorumBitmapHistoryLib} from "../../src/libraries/QuorumBitmapHistoryLib.sol"; import {BitmapUtils} from "../../src/libraries/BitmapUtils.sol"; import {console} from "forge-std/console.sol"; @@ -35,7 +41,10 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { // emitted when an operator's index in the orderd operator list for the quorum with number `quorumNumber` is updated event QuorumIndexUpdate(bytes32 indexed operatorId, uint8 quorumNumber, uint32 newIndex); - event OperatorSetParamsUpdated(uint8 indexed quorumNumber, ISlashingRegistryCoordinator.OperatorSetParam operatorSetParams); + event OperatorSetParamsUpdated( + uint8 indexed quorumNumber, + ISlashingRegistryCoordinatorTypes.OperatorSetParam operatorSetParams + ); event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); @@ -51,11 +60,14 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { uint256 pseudoRandomNumber, bytes memory quorumNumbers, uint96 operatorToKickStake - ) internal returns( - address operatorToRegister, - BN254.G1Point memory operatorToRegisterPubKey, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams - ) { + ) + internal + returns ( + address operatorToRegister, + BN254.G1Point memory operatorToRegisterPubKey, + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams + ) + { uint32 kickRegistrationBlockNumber = 100; uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); @@ -78,7 +90,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { address operatorToKick; // register last operator before kick - operatorKickParams = new ISlashingRegistryCoordinator.OperatorKickParam[](1); + operatorKickParams = new ISlashingRegistryCoordinatorTypes.OperatorKickParam[](1); { BN254.G1Point memory pubKey = BN254.hashToG1( keccak256(abi.encodePacked(pseudoRandomNumber, defaultMaxOperatorCount - 1)) @@ -95,7 +107,7 @@ contract RegistryCoordinatorUnitTests is MockAVSDeployer { // operatorIdsToSwap[0] = operatorToRegisterId operatorIdsToSwap[0] = operatorToRegisterId; - operatorKickParams[0] = ISlashingRegistryCoordinator.OperatorKickParam({ + operatorKickParams[0] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: uint8(quorumNumbers[0]), operator: operatorToKick }); @@ -125,7 +137,7 @@ contract RegistryCoordinatorUnitTests_Initialization_Setters is RegistryCoordina registryCoordinatorOwner, churnApprover, ejector, - 0/*initialPausedStatus*/, + 0, // _initialPausedStatus address(serviceManager) // _accountIdentifier ); } @@ -200,9 +212,9 @@ contract RegistryCoordinatorUnitTests_Initialization_Setters is RegistryCoordina } function test_createQuorum_revert_notOwner() public { - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams; + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams; uint96 minimumStake; - IStakeRegistry.StrategyParams[] memory strategyParams; + IStakeRegistryTypes.StrategyParams[] memory strategyParams; cheats.expectRevert("Ownable: caller is not the owner"); cheats.prank(defaultOperator); @@ -216,17 +228,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); - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = - ISlashingRegistryCoordinator.OperatorSetParam({ - maxOperatorCount: defaultMaxOperatorCount, - kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, - kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake - }); + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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(); @@ -332,19 +346,29 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni assertEq(registryCoordinator.getOperatorId(defaultOperator), defaultOperatorId); assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: uint32(block.number), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } @@ -390,19 +414,29 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni assertEq(registryCoordinator.getOperatorId(defaultOperator), defaultOperatorId); assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: uint32(block.number), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } @@ -447,27 +481,43 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni assertEq(registryCoordinator.getOperatorId(defaultOperator), defaultOperatorId); assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers)), - updateBlockNumber: uint32(registrationBlockNumber), - nextUpdateBlockNumber: uint32(nextRegistrationBlockNumber) - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers)), + updateBlockNumber: uint32(registrationBlockNumber), + nextUpdateBlockNumber: uint32(nextRegistrationBlockNumber) + }) + ) + ) ); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: uint32(nextRegistrationBlockNumber), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: uint32(nextRegistrationBlockNumber), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } @@ -595,12 +645,18 @@ contract RegistryCoordinatorUnitTests_RegisterOperator is RegistryCoordinatorUni assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: uint32(block.number), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } } @@ -643,6 +699,8 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is cheats.prank(registryCoordinator.owner()); registryCoordinator.enableOperatorSets(); + console.log("quorumCount", registryCoordinator.quorumCount()); + assertTrue( registryCoordinator.isM2Quorum(uint8(defaultQuorumNumber)), "defaultQuorumNumber should be a M2 quorum" @@ -652,7 +710,6 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is quorumNumbers[0] = bytes1(defaultQuorumNumber); uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); - quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); @@ -696,19 +753,29 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: registrationBlockNumber, - nextUpdateBlockNumber: deregistrationBlockNumber - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: registrationBlockNumber, + nextUpdateBlockNumber: deregistrationBlockNumber + }) + ) + ) ); } @@ -755,19 +822,29 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: registrationBlockNumber, - nextUpdateBlockNumber: deregistrationBlockNumber - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: registrationBlockNumber, + nextUpdateBlockNumber: deregistrationBlockNumber + }) + ) + ) ); } // @notice verifies that an operator who was registered for a fuzzed set of quorums can be deregistered from a subset of those quorums @@ -826,18 +903,26 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is if (deregistrationQuorumBitmap == registrationQuorumBitmap) { assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); } else { assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); } // ensure that the operator's current quorum bitmap matches the expectation @@ -848,22 +933,36 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ); // check that the quorum bitmap history is as expected assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(registrationQuorumBitmap), - updateBlockNumber: registrationBlockNumber, - nextUpdateBlockNumber: deregistrationBlockNumber - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(registrationQuorumBitmap), + updateBlockNumber: registrationBlockNumber, + nextUpdateBlockNumber: deregistrationBlockNumber + }) + ) + ) ); // note: there will be no second entry in the operator's bitmap history in the event that the operator has totally deregistered if (deregistrationQuorumBitmap != registrationQuorumBitmap) { assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(expectedQuorumBitmap), - updateBlockNumber: deregistrationBlockNumber, - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode( + registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1) + ) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(expectedQuorumBitmap), + updateBlockNumber: deregistrationBlockNumber, + nextUpdateBlockNumber: 0 + }) + ) + ) ); } } @@ -940,19 +1039,31 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is assertEq( keccak256(abi.encode(registryCoordinator.getOperator(operatorToDeregister))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: operatorToDeregisterId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: operatorToDeregisterId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToDeregisterId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(operatorToDeregisterQuorumBitmap), - updateBlockNumber: registrationBlockNumber, - nextUpdateBlockNumber: deregistrationBlockNumber - }))) + keccak256( + abi.encode( + registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToDeregisterId, 0) + ) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(operatorToDeregisterQuorumBitmap), + updateBlockNumber: registrationBlockNumber, + nextUpdateBlockNumber: deregistrationBlockNumber + }) + ) + ) ); } @@ -971,7 +1082,7 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is cheats.roll(reregistrationBlockNumber); // store data before registering, to check against later - ISlashingRegistryCoordinator.QuorumBitmapUpdate memory previousQuorumBitmapUpdate = + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate memory previousQuorumBitmapUpdate = registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0); // re-register the operator @@ -983,10 +1094,14 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is assertEq(registryCoordinator.getOperatorId(defaultOperator), defaultOperatorId, "1"); assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ), "2" ); assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap, "3"); @@ -1001,12 +1116,22 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is // check that new entry in bitmap history is as expected uint256 historyLength = registryCoordinator.getQuorumBitmapHistoryLength(defaultOperatorId); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, historyLength - 1))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: uint32(reregistrationBlockNumber), - nextUpdateBlockNumber: 0 - }))), + keccak256( + abi.encode( + registryCoordinator.getQuorumBitmapUpdateByIndex( + defaultOperatorId, historyLength - 1 + ) + ) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: uint32(reregistrationBlockNumber), + nextUpdateBlockNumber: 0 + }) + ) + ), "5" ); } @@ -1181,18 +1306,26 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is if (deregistrationQuorumBitmap == registrationQuorumBitmap) { assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); } else { assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); } // ensure that the operator's current quorum bitmap matches the expectation @@ -1203,22 +1336,36 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is ); // check that the quorum bitmap history is as expected assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(registrationQuorumBitmap), - updateBlockNumber: registrationBlockNumber, - nextUpdateBlockNumber: deregistrationBlockNumber - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(registrationQuorumBitmap), + updateBlockNumber: registrationBlockNumber, + nextUpdateBlockNumber: deregistrationBlockNumber + }) + ) + ) ); // note: there will be no second entry in the operator's bitmap history in the event that the operator has totally deregistered if (deregistrationQuorumBitmap != registrationQuorumBitmap) { assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(expectedQuorumBitmap), - updateBlockNumber: deregistrationBlockNumber, - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode( + registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1) + ) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(expectedQuorumBitmap), + updateBlockNumber: deregistrationBlockNumber, + nextUpdateBlockNumber: 0 + }) + ) + ) ); } } @@ -1249,10 +1396,14 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is // make sure the operator is deregistered assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); // make sure the operator is not in any quorums assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); @@ -1290,10 +1441,14 @@ contract RegistryCoordinatorUnitTests_DeregisterOperator_EjectOperator is // make sure the operator is registered assertEq( keccak256(abi.encode(registryCoordinator.getOperator(defaultOperator))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: defaultOperatorId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: defaultOperatorId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); // make sure the operator is properly removed from the quorums assertEq( @@ -1524,7 +1679,8 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord address operatorToKick; // register last operator before kick - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams = new ISlashingRegistryCoordinator.OperatorKickParam[](1); + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams = + new ISlashingRegistryCoordinatorTypes.OperatorKickParam[](1); { BN254.G1Point memory pubKey = BN254.hashToG1(keccak256(abi.encodePacked(pseudoRandomNumber, numOperators - 1))); @@ -1537,7 +1693,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord // operatorIdsToSwap[0] = operatorToRegisterId operatorIdsToSwap[0] = operatorToRegisterId; - operatorKickParams[0] = ISlashingRegistryCoordinator.OperatorKickParam({ + operatorKickParams[0] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ quorumNumber: defaultQuorumNumber, operator: operatorToKick }); @@ -1563,7 +1719,9 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord cheats.expectEmit(true, true, true, true, address(registryCoordinator)); emit OperatorDeregistered(operatorKickParams[0].operator, operatorToKickId); cheats.expectEmit(true, true, true, true, address(blsApkRegistry)); - emit OperatorRemovedFromQuorums(operatorKickParams[0].operator, operatorToKickId, quorumNumbers); + emit OperatorRemovedFromQuorums( + operatorKickParams[0].operator, operatorToKickId, quorumNumbers + ); cheats.expectEmit(true, true, true, true, address(stakeRegistry)); emit OperatorStakeUpdate(operatorToKickId, defaultQuorumNumber, 0); cheats.expectEmit(true, true, true, true, address(indexRegistry)); @@ -1597,25 +1755,39 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord assertEq( keccak256(abi.encode(registryCoordinator.getOperator(operatorToRegister))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: operatorToRegisterId, - status: ISlashingRegistryCoordinator.OperatorStatus.REGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: operatorToRegisterId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.REGISTERED + }) + ) + ) ); assertEq( keccak256(abi.encode(registryCoordinator.getOperator(operatorToKick))), - keccak256(abi.encode(ISlashingRegistryCoordinator.OperatorInfo({ - operatorId: operatorToKickId, - status: ISlashingRegistryCoordinator.OperatorStatus.DEREGISTERED - }))) + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.OperatorInfo({ + operatorId: operatorToKickId, + status: ISlashingRegistryCoordinatorTypes.OperatorStatus.DEREGISTERED + }) + ) + ) ); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToKickId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(quorumBitmap), - updateBlockNumber: kickRegistrationBlockNumber, - nextUpdateBlockNumber: registrationBlockNumber - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToKickId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(quorumBitmap), + updateBlockNumber: kickRegistrationBlockNumber, + nextUpdateBlockNumber: registrationBlockNumber + }) + ) + ) ); } @@ -1629,7 +1801,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); @@ -1667,15 +1839,17 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams - ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, operatorToKickStake); + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams + ) = _test_registerOperatorWithChurn_SetUp( + pseudoRandomNumber, quorumNumbers, operatorToKickStake + ); bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); // set the stake of the operator to register to the defaultKickBIPsOfOperatorStake multiple of the operatorToKickStake _setOperatorWeight( operatorToRegister, defaultQuorumNumber, - operatorToKickStake * defaultKickBIPsOfOperatorStake / 10_000 + 1 + operatorToKickStake * defaultKickBIPsOfOperatorStake / 10000 + 1 ); cheats.roll(registrationBlockNumber); @@ -1709,7 +1883,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, , - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); uint96 registeringStake = defaultKickBIPsOfOperatorStake * defaultStake; @@ -1743,7 +1917,7 @@ contract RegistryCoordinatorUnitTests_RegisterOperatorWithChurn is RegistryCoord ( address operatorToRegister, BN254.G1Point memory operatorToRegisterPubKey, - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, defaultStake); bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); @@ -2073,7 +2247,7 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit ), keccak256( abi.encode( - ISlashingRegistryCoordinator.QuorumBitmapUpdate({ + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ quorumBitmap: uint192(newBitmap), updateBlockNumber: uint32(block.number), nextUpdateBlockNumber: 0 @@ -2092,12 +2266,18 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit registryCoordinator._updateOperatorBitmapExternal(defaultOperatorId, newBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(newBitmap), - updateBlockNumber: uint32(block.number), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(newBitmap), + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } @@ -2114,20 +2294,32 @@ contract RegistryCoordinatorUnitTests_UpdateOperators is RegistryCoordinatorUnit registryCoordinator._updateOperatorBitmapExternal(defaultOperatorId, newBitmap); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(pastBitmap), - updateBlockNumber: uint32(previousBlockNumber), - nextUpdateBlockNumber: uint32(block.number) - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(pastBitmap), + updateBlockNumber: uint32(previousBlockNumber), + nextUpdateBlockNumber: uint32(block.number) + }) + ) + ) ); assertEq( - keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), - keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ - quorumBitmap: uint192(newBitmap), - updateBlockNumber: uint32(block.number), - nextUpdateBlockNumber: 0 - }))) + keccak256( + abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1)) + ), + keccak256( + abi.encode( + ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ + quorumBitmap: uint192(newBitmap), + updateBlockNumber: uint32(block.number), + nextUpdateBlockNumber: 0 + }) + ) + ) ); } } @@ -2152,16 +2344,19 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit function test_CreateTotalDelegatedStakeQuorum() public { _deployMockEigenLayerAndAVS(0); // Set up test params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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(); @@ -2176,7 +2371,8 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit assertEq(registryCoordinator.quorumCount(), initialQuorumCount + 1); // Verify quorum params were set correctly - ISlashingRegistryCoordinator.OperatorSetParam memory storedParams = registryCoordinator.getOperatorSetParams(initialQuorumCount); + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory storedParams = + registryCoordinator.getOperatorSetParams(initialQuorumCount); assertEq(storedParams.maxOperatorCount, operatorSetParams.maxOperatorCount); assertEq(storedParams.kickBIPsOfOperatorStake, operatorSetParams.kickBIPsOfOperatorStake); assertEq(storedParams.kickBIPsOfTotalStake, operatorSetParams.kickBIPsOfTotalStake); @@ -2184,16 +2380,19 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit function test_CreateSlashableStakeQuorum_Reverts() public { _deployMockEigenLayerAndAVS(0); - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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 @@ -2213,7 +2412,6 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit } contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitTests { - function test_MigrateToOperatorSets() public { cheats.prank(registryCoordinatorOwner); registryCoordinator.enableOperatorSets(); @@ -2230,8 +2428,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)]}) @@ -2261,8 +2459,13 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT assertEq(bitmap, 0, "Operator bitmap should be empty after deregistration"); // Verify operator status is NEVER_REGISTERED - ISlashingRegistryCoordinator.OperatorStatus status = registryCoordinator.getOperatorStatus(operatorToRegister); - assertEq(uint8(status), uint8(ISlashingRegistryCoordinator.OperatorStatus.NEVER_REGISTERED), "Operator status should be NEVER_REGISTERED"); + ISlashingRegistryCoordinatorTypes.OperatorStatus status = + registryCoordinator.getOperatorStatus(operatorToRegister); + assertEq( + uint8(status), + uint8(ISlashingRegistryCoordinatorTypes.OperatorStatus.NEVER_REGISTERED), + "Operator status should be NEVER_REGISTERED" + ); } function test_M2_Register_Reverts() public { @@ -2271,7 +2474,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(); @@ -2289,16 +2492,17 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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 @@ -2317,16 +2521,17 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2345,44 +2550,38 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); - registryCoordinator.createTotalDelegatedStakeQuorum( - operatorSetParams, - 0, - strategyParams - ); + registryCoordinator.createTotalDelegatedStakeQuorum(operatorSetParams, 0, strategyParams); uint32[] memory operatorSetIds = new uint32[](1); 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 // }); // Encode with RegistrationType.NORMAL - bytes memory data = abi.encode( - ISlashingRegistryCoordinator.RegistrationType.NORMAL, - socket, - params - ); + bytes memory data = + abi.encode(ISlashingRegistryCoordinatorTypes.RegistrationType.NORMAL, socket, params); cheats.prank(address(registryCoordinator.allocationManager())); registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); @@ -2396,17 +2595,18 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2416,16 +2616,17 @@ 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 // }); - ISlashingRegistryCoordinator.OperatorKickParam[] memory operatorKickParams = new ISlashingRegistryCoordinator.OperatorKickParam[](1); - operatorKickParams[0] = ISlashingRegistryCoordinator.OperatorKickParam({ + ISlashingRegistryCoordinatorTypes.OperatorKickParam[] memory operatorKickParams = + new ISlashingRegistryCoordinatorTypes.OperatorKickParam[](1); + operatorKickParams[0] = ISlashingRegistryCoordinatorTypes.OperatorKickParam({ operator: address(0x1), quorumNumber: 0 }); @@ -2434,7 +2635,7 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT // Encode with RegistrationType.CHURN bytes memory data = abi.encode( - ISlashingRegistryCoordinator.RegistrationType.CHURN, + ISlashingRegistryCoordinatorTypes.RegistrationType.CHURN, socket, params, operatorKickParams, @@ -2450,17 +2651,18 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT vm.skip(true); _deployMockEigenLayerAndAVS(0); - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake }); 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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); cheats.prank(registryCoordinatorOwner); registryCoordinator.createTotalDelegatedStakeQuorum( @@ -2479,17 +2681,18 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2500,20 +2703,17 @@ 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 // }); // Encode with RegistrationType.NORMAL - bytes memory data = abi.encode( - ISlashingRegistryCoordinator.RegistrationType.NORMAL, - socket, - params - ); + bytes memory data = + abi.encode(ISlashingRegistryCoordinatorTypes.RegistrationType.NORMAL, socket, params); cheats.startPrank(address(registryCoordinator.allocationManager())); registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); @@ -2531,44 +2731,38 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT registryCoordinator.enableOperatorSets(); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); - registryCoordinator.createTotalDelegatedStakeQuorum( - operatorSetParams, - 0, - strategyParams - ); + registryCoordinator.createTotalDelegatedStakeQuorum(operatorSetParams, 0, strategyParams); uint32[] memory operatorSetIds = new uint32[](1); 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 // }); // Encode with RegistrationType.NORMAL - bytes memory data = abi.encode( - ISlashingRegistryCoordinator.RegistrationType.NORMAL, - socket, - params - ); + bytes memory data = + abi.encode(ISlashingRegistryCoordinatorTypes.RegistrationType.NORMAL, socket, params); vm.expectRevert(); registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); @@ -2581,23 +2775,21 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT cheats.prank(registryCoordinatorOwner); registryCoordinator.enableOperatorSets(); - assertTrue( - registryCoordinator.operatorSetsEnabled(), - "operatorSetsEnabled should be true" - ); + assertTrue(registryCoordinator.operatorSetsEnabled(), "operatorSetsEnabled should be true"); // Create quorum params - ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = + ISlashingRegistryCoordinatorTypes.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: 10_000}); + IStakeRegistryTypes.StrategyParams({strategy: IStrategy(address(1)), multiplier: 10000}); // Create total delegated stake quorum cheats.prank(registryCoordinatorOwner); @@ -2608,19 +2800,16 @@ 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 // }); - bytes memory data = abi.encode( - ISlashingRegistryCoordinator.RegistrationType.NORMAL, - socket, - params - ); + bytes memory data = + abi.encode(ISlashingRegistryCoordinatorTypes.RegistrationType.NORMAL, socket, params); cheats.prank(address(registryCoordinator.allocationManager())); registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); diff --git a/test/unit/ServiceManagerBase.t.sol b/test/unit/ServiceManagerBase.t.sol index d293f088..d9647ce8 100644 --- a/test/unit/ServiceManagerBase.t.sol +++ b/test/unit/ServiceManagerBase.t.sol @@ -24,7 +24,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve uint32 MAX_REWARDS_DURATION = 70 days; uint32 MAX_RETROACTIVE_LENGTH = 84 days; uint32 MAX_FUTURE_LENGTH = 28 days; - uint32 GENESIS_REWARDS_TIMESTAMP = 1_712_188_800; + uint32 GENESIS_REWARDS_TIMESTAMP = 1712188800; uint256 MAX_REWARDS_AMOUNT = 1e38 - 1; uint32 OPERATOR_SET_GENESIS_REWARDS_TIMESTAMP = 0; /// TODO: what values should these have diff --git a/test/unit/SlashingRegistryCoordinatorUnit.t.sol b/test/unit/SlashingRegistryCoordinatorUnit.t.sol index 52d12ed8..844aa6e9 100644 --- a/test/unit/SlashingRegistryCoordinatorUnit.t.sol +++ b/test/unit/SlashingRegistryCoordinatorUnit.t.sol @@ -7,7 +7,6 @@ // import {BitmapUtils} from "../../src/libraries/BitmapUtils.sol"; // import {console} from "forge-std/console.sol"; - // contract RegistryCoordinatorUnitTests is MockAVSDeployer { // using BN254 for BN254.G1Point; @@ -47,7 +46,7 @@ // // emitted when an operator's index in the orderd operator list for the quorum with number `quorumNumber` is updated // event QuorumIndexUpdate(bytes32 indexed operatorId, uint8 quorumNumber, uint32 newIndex); -// event OperatorSetParamsUpdated(uint8 indexed quorumNumber, ISlashingRegistryCoordinator.OperatorSetParam operatorSetParams); +// event OperatorSetParamsUpdated(uint8 indexed quorumNumber, ISlashingRegistryCoordinatorTypes.OperatorSetParam operatorSetParams); // event ChurnApproverUpdated(address prevChurnApprover, address newChurnApprover); @@ -204,9 +203,9 @@ // } // function test_createQuorum_revert_notOwner() public { -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams; +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams; // uint96 minimumStake; -// IStakeRegistry.StrategyParams[] memory strategyParams; +// IStakeRegistryTypes.StrategyParams[] memory strategyParams; // cheats.expectRevert("Ownable: caller is not the owner"); // cheats.prank(defaultOperator); @@ -218,16 +217,16 @@ // // this is necessary since the default setup already configures the max number of quorums, preventing adding more // _deployMockEigenLayerAndAVS(0); -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = -// ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = +// ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: defaultMaxOperatorCount, // kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, // kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake // }); // uint96 minimumStake = 1; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); // strategyParams[0] = -// IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1000)), // multiplier: 1e16 // }); @@ -333,7 +332,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -390,7 +389,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -441,7 +440,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers)), // updateBlockNumber: uint32(registrationBlockNumber), // nextUpdateBlockNumber: uint32(nextRegistrationBlockNumber) @@ -449,7 +448,7 @@ // ); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: uint32(nextRegistrationBlockNumber), // nextUpdateBlockNumber: 0 @@ -570,7 +569,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), quorumBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -663,7 +662,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: registrationBlockNumber, // nextUpdateBlockNumber: deregistrationBlockNumber @@ -718,7 +717,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: registrationBlockNumber, // nextUpdateBlockNumber: deregistrationBlockNumber @@ -794,7 +793,7 @@ // // check that the quorum bitmap history is as expected // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(registrationQuorumBitmap), // updateBlockNumber: registrationBlockNumber, // nextUpdateBlockNumber: deregistrationBlockNumber @@ -804,7 +803,7 @@ // if (deregistrationQuorumBitmap != registrationQuorumBitmap) { // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(expectedQuorumBitmap), // updateBlockNumber: deregistrationBlockNumber, // nextUpdateBlockNumber: 0 @@ -880,7 +879,7 @@ // assertEq(registryCoordinator.getCurrentQuorumBitmap(defaultOperatorId), 0); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToDeregisterId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(operatorToDeregisterQuorumBitmap), // updateBlockNumber: registrationBlockNumber, // nextUpdateBlockNumber: deregistrationBlockNumber @@ -930,7 +929,7 @@ // uint historyLength = registryCoordinator.getQuorumBitmapHistoryLength(defaultOperatorId); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, historyLength - 1))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: uint32(reregistrationBlockNumber), // nextUpdateBlockNumber: 0 @@ -1109,7 +1108,7 @@ // // check that the quorum bitmap history is as expected // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(registrationQuorumBitmap), // updateBlockNumber: registrationBlockNumber, // nextUpdateBlockNumber: deregistrationBlockNumber @@ -1119,7 +1118,7 @@ // if (deregistrationQuorumBitmap != registrationQuorumBitmap) { // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(expectedQuorumBitmap), // updateBlockNumber: deregistrationBlockNumber, // nextUpdateBlockNumber: 0 @@ -1393,7 +1392,6 @@ // cheats.expectEmit(true, true, true, true, address(indexRegistry)); // emit QuorumIndexUpdate(operatorToRegisterId, defaultQuorumNumber, numOperators); - // cheats.expectEmit(true, true, true, true, address(registryCoordinator)); // emit OperatorDeregistered(operatorKickParams[0].operator, operatorToKickId); // cheats.expectEmit(true, true, true, true, address(blsApkRegistry)); @@ -1437,7 +1435,7 @@ // ); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(operatorToKickId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(quorumBitmap), // updateBlockNumber: kickRegistrationBlockNumber, // nextUpdateBlockNumber: registrationBlockNumber @@ -1487,7 +1485,6 @@ // ) = _test_registerOperatorWithChurn_SetUp(pseudoRandomNumber, quorumNumbers, operatorToKickStake); // bytes32 operatorToRegisterId = BN254.hashG1Point(operatorToRegisterPubKey); - // // set the stake of the operator to register to the defaultKickBIPsOfOperatorStake multiple of the operatorToKickStake // _setOperatorWeight(operatorToRegister, defaultQuorumNumber, operatorToKickStake * defaultKickBIPsOfOperatorStake / 10000 + 1); @@ -1834,7 +1831,7 @@ // registryCoordinator._updateOperatorBitmapExternal(defaultOperatorId, newBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(newBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -1850,7 +1847,7 @@ // registryCoordinator._updateOperatorBitmapExternal(defaultOperatorId, newBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(newBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -1870,7 +1867,7 @@ // registryCoordinator._updateOperatorBitmapExternal(defaultOperatorId, newBitmap); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(pastBitmap), // updateBlockNumber: uint32(previousBlockNumber), // nextUpdateBlockNumber: uint32(block.number) @@ -1878,7 +1875,7 @@ // ); // assertEq( // keccak256(abi.encode(registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 1))), -// keccak256(abi.encode(ISlashingRegistryCoordinator.QuorumBitmapUpdate({ +// keccak256(abi.encode(ISlashingRegistryCoordinatorTypes.QuorumBitmapUpdate({ // quorumBitmap: uint192(newBitmap), // updateBlockNumber: uint32(block.number), // nextUpdateBlockNumber: 0 @@ -1905,14 +1902,14 @@ // function test_CreateTotalDelegatedStakeQuorum() public { // _deployMockEigenLayerAndAVS(0); // // Set up test params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 0, // kickBIPsOfTotalStake: 0 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(0x1)), // multiplier: 1000 // }); @@ -1932,7 +1929,7 @@ // assertEq(registryCoordinator.quorumCount(), initialQuorumCount + 1); // // Verify quorum params were set correctly -// ISlashingRegistryCoordinator.OperatorSetParam memory storedParams = registryCoordinator.getOperatorSetParams(initialQuorumCount); +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory storedParams = registryCoordinator.getOperatorSetParams(initialQuorumCount); // assertEq(storedParams.maxOperatorCount, operatorSetParams.maxOperatorCount); // assertEq(storedParams.kickBIPsOfOperatorStake, operatorSetParams.kickBIPsOfOperatorStake); // assertEq(storedParams.kickBIPsOfTotalStake, operatorSetParams.kickBIPsOfTotalStake); @@ -1940,14 +1937,14 @@ // function test_CreateSlashableStakeQuorum_Reverts() public { // _deployMockEigenLayerAndAVS(0); -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 0, // kickBIPsOfTotalStake: 0 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(0x1)), // multiplier: 1000 // }); @@ -1992,7 +1989,7 @@ // expiry: 0 // }); -// IBLSApkRegistry.PubkeyRegistrationParams memory operatorRegisterApkParams = IBLSApkRegistry.PubkeyRegistrationParams({ +// IBLSApkRegistryTypes.PubkeyRegistrationParams memory operatorRegisterApkParams = IBLSApkRegistryTypes.PubkeyRegistrationParams({ // pubkeyRegistrationSignature: BN254.G1Point({ // X: 0, // Y: 0 @@ -2041,7 +2038,7 @@ // 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(); @@ -2062,14 +2059,14 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 1 // }); @@ -2094,14 +2091,14 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2124,15 +2121,15 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2145,14 +2142,13 @@ // strategyParams // ); - // uint32[] memory operatorSetIds = new uint32[](1); // 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 @@ -2171,15 +2167,15 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2196,9 +2192,9 @@ // 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 @@ -2230,15 +2226,15 @@ // vm.skip(true); // _deployMockEigenLayerAndAVS(0); -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: defaultMaxOperatorCount, // kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, // kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2263,15 +2259,15 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2289,9 +2285,9 @@ // 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 @@ -2299,7 +2295,6 @@ // bytes memory data = abi.encode(socket, params); - // cheats.startPrank(address(registryCoordinator.allocationManager())); // registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); @@ -2316,15 +2311,15 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2337,14 +2332,13 @@ // strategyParams // ); - // uint32[] memory operatorSetIds = new uint32[](1); // 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 @@ -2364,15 +2358,15 @@ // registryCoordinator.enableOperatorSets(); // // Create quorum params -// ISlashingRegistryCoordinator.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinator.OperatorSetParam({ +// ISlashingRegistryCoordinatorTypes.OperatorSetParam memory operatorSetParams = ISlashingRegistryCoordinatorTypes.OperatorSetParam({ // maxOperatorCount: 10, // kickBIPsOfOperatorStake: 1000, // kickBIPsOfTotalStake: 100 // }); // uint96 minimumStake = 100; -// IStakeRegistry.StrategyParams[] memory strategyParams = new IStakeRegistry.StrategyParams[](1); -// strategyParams[0] = IStakeRegistry.StrategyParams({ +// IStakeRegistryTypes.StrategyParams[] memory strategyParams = new IStakeRegistryTypes.StrategyParams[](1); +// strategyParams[0] = IStakeRegistryTypes.StrategyParams({ // strategy: IStrategy(address(1)), // multiplier: 10000 // }); @@ -2390,9 +2384,9 @@ // 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 @@ -2400,7 +2394,6 @@ // bytes memory data = abi.encode(socket, params); - // cheats.prank(address(registryCoordinator.allocationManager())); // registryCoordinator.registerOperator(defaultOperator, operatorSetIds, data); // cheats.stopPrank(); diff --git a/test/unit/StakeRegistryUnit.t.sol b/test/unit/StakeRegistryUnit.t.sol index 2352dfeb..bd3ea670 100644 --- a/test/unit/StakeRegistryUnit.t.sol +++ b/test/unit/StakeRegistryUnit.t.sol @@ -56,7 +56,10 @@ contract StakeRegistryUnitTests is MockAVSDeployer, IStakeRegistryEvents { ); stakeRegistryImplementation = new StakeRegistryHarness( - ISlashingRegistryCoordinator(address(registryCoordinator)), delegationMock, avsDirectoryMock, allocationManager + ISlashingRegistryCoordinator(address(registryCoordinator)), + delegationMock, + avsDirectoryMock, + allocationManager ); stakeRegistry = StakeRegistryHarness( @@ -95,9 +98,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) ); @@ -107,8 +110,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)); @@ -123,10 +130,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) ); @@ -583,7 +590,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.OnlySlashingRegistryCoordinator.selector); stakeRegistry.initializeDelegatedStakeQuorum(quorumNumber, minimumStake, strategyParams); @@ -592,7 +599,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)); @@ -604,15 +611,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) ); } @@ -621,46 +628,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" + ); } /** @@ -674,11 +689,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] ); } @@ -764,7 +779,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.OnlySlashingRegistryCoordinatorOwner.selector); stakeRegistry.addStrategies(quorumNumber, strategyParams); @@ -772,7 +787,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); @@ -786,10 +801,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); @@ -801,9 +816,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); @@ -828,11 +843,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); @@ -1878,7 +1893,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" ); @@ -2091,7 +2106,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" ); @@ -2167,8 +2182,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({ @@ -2182,8 +2197,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; @@ -2219,18 +2235,18 @@ contract StakeRegistryUnitTests_weightOfOperatorForQuorum is StakeRegistryUnitTe ) public { // 3 LST Strat multipliers, rETH, stETH, ETH uint96[] memory multipliers = new uint96[](3); - multipliers[0] = uint96(1_070_136_092_289_993_178); - multipliers[1] = uint96(1_071_364_636_818_145_808); - multipliers[2] = uint96(1_000_000_000_000_000_000); + multipliers[0] = uint96(1070136092289993178); + multipliers[1] = uint96(1071364636818145808); + multipliers[2] = uint96(1000000000000000000); - 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/BLSMockAVSDeployer.sol b/test/utils/BLSMockAVSDeployer.sol index 84890944..701fd320 100644 --- a/test/utils/BLSMockAVSDeployer.sol +++ b/test/utils/BLSMockAVSDeployer.sol @@ -31,23 +31,23 @@ contract BLSMockAVSDeployer is MockAVSDeployer { function _setAggregatePublicKeysAndSignature() internal { // aggSignerPrivKey*g2 aggSignerApkG2.X[1] = - 19_101_821_850_089_705_274_637_533_855_249_918_363_070_101_489_527_618_151_493_230_256_975_900_223_847; + 19101821850089705274637533855249918363070101489527618151493230256975900223847; aggSignerApkG2.X[0] = - 5_334_410_886_741_819_556_325_359_147_377_682_006_012_228_123_419_628_681_352_847_439_302_316_235_957; + 5334410886741819556325359147377682006012228123419628681352847439302316235957; aggSignerApkG2.Y[1] = - 354_176_189_041_917_478_648_604_979_334_478_067_325_821_134_838_555_150_300_539_079_146_482_658_331; + 354176189041917478648604979334478067325821134838555150300539079146482658331; aggSignerApkG2.Y[0] = - 4_185_483_097_059_047_421_902_184_823_581_361_466_320_657_066_600_218_863_748_375_739_772_335_928_910; + 4185483097059047421902184823581361466320657066600218863748375739772335928910; // 100*aggSignerPrivKey*g2 oneHundredQuorumApkG2.X[1] = - 6_187_649_255_575_786_743_153_792_867_265_230_878_737_103_598_736_372_524_337_965_086_852_090_105_771; + 6187649255575786743153792867265230878737103598736372524337965086852090105771; oneHundredQuorumApkG2.X[0] = - 5_334_877_400_925_935_887_383_922_877_430_837_542_135_722_474_116_902_175_395_820_705_628_447_222_839; + 5334877400925935887383922877430837542135722474116902175395820705628447222839; oneHundredQuorumApkG2.Y[1] = - 4_668_116_328_019_846_503_695_710_811_760_363_536_142_902_258_271_850_958_815_598_072_072_236_299_223; + 4668116328019846503695710811760363536142902258271850958815598072072236299223; oneHundredQuorumApkG2.Y[0] = - 21_446_056_442_597_180_561_077_194_011_672_151_329_458_819_211_586_246_807_143_487_001_691_968_661_015; + 21446056442597180561077194011672151329458819211586246807143487001691968661015; sigma = BN254.hashToG1(msgHash).scalar_mul(aggSignerPrivKey); } diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 20bdbb1d..eb5ac6a7 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -16,12 +16,16 @@ import {RegistryCoordinator} from "../../src/RegistryCoordinator.sol"; import {RegistryCoordinatorHarness} from "../harnesses/RegistryCoordinatorHarness.t.sol"; import {BLSApkRegistry} from "../../src/BLSApkRegistry.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"; import {IIndexRegistry} from "../../src/interfaces/IIndexRegistry.sol"; import {IRegistryCoordinator} from "../../src/interfaces/IRegistryCoordinator.sol"; +import { + ISlashingRegistryCoordinatorTypes, + ISlashingRegistryCoordinatorTypes +} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; import {ISlashingRegistryCoordinator} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; import {IServiceManager} from "../../src/interfaces/IServiceManager.sol"; @@ -106,19 +110,19 @@ contract MockAVSDeployer is Test { address defaultOperator = address(uint160(uint256(keccak256("defaultOperator")))); bytes32 defaultOperatorId; BN254.G1Point internal defaultPubKey = BN254.G1Point( - 18_260_007_818_883_133_054_078_754_218_619_977_578_772_505_796_600_400_998_181_738_095_793_040_006_897, - 3_432_351_341_799_135_763_167_709_827_653_955_074_218_841_517_684_851_694_584_291_831_827_675_065_899 + 18260007818883133054078754218619977578772505796600400998181738095793040006897, + 3432351341799135763167709827653955074218841517684851694584291831827675065899 ); string defaultSocket = "69.69.69.69:420"; uint96 defaultStake = 1 ether; uint8 defaultQuorumNumber = 0; uint32 defaultMaxOperatorCount = 10; - uint16 defaultKickBIPsOfOperatorStake = 15_000; + uint16 defaultKickBIPsOfOperatorStake = 15000; uint16 defaultKickBIPsOfTotalStake = 150; uint8 numQuorums = 192; - ISlashingRegistryCoordinator.OperatorSetParam[] operatorSetParams; + ISlashingRegistryCoordinatorTypes.OperatorSetParam[] operatorSetParams; uint8 maxQuorumsToRegisterFor = 4; uint256 maxOperatorsToRegister = 4; @@ -211,8 +215,12 @@ contract MockAVSDeployer is Test { cheats.startPrank(proxyAdminOwner); - stakeRegistryImplementation = - new StakeRegistryHarness(ISlashingRegistryCoordinator(registryCoordinator), delegationMock, avsDirectory, allocationManagerMock); + stakeRegistryImplementation = new StakeRegistryHarness( + ISlashingRegistryCoordinator(registryCoordinator), + delegationMock, + avsDirectory, + allocationManagerMock + ); proxyAdmin.upgrade( TransparentUpgradeableProxy(payable(address(stakeRegistry))), address(stakeRegistryImplementation) @@ -270,11 +278,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) ); } @@ -307,7 +316,7 @@ contract MockAVSDeployer is Test { for (uint256 i = 0; i < numQuorumsToAdd; i++) { // hard code these for now operatorSetParams.push( - ISlashingRegistryCoordinator.OperatorSetParam({ + ISlashingRegistryCoordinatorTypes.OperatorSetParam({ maxOperatorCount: defaultMaxOperatorCount, kickBIPsOfOperatorStake: defaultKickBIPsOfOperatorStake, kickBIPsOfTotalStake: defaultKickBIPsOfTotalStake @@ -326,7 +335,6 @@ contract MockAVSDeployer is Test { quorumStrategiesConsideredAndMultipliers[i] ); } - } operatorStateRetriever = new OperatorStateRetriever();