diff --git a/script/deploy/devnet/deploy_from_scratch.s.sol b/script/deploy/devnet/deploy_from_scratch.s.sol index 107a9b16e..33bb92320 100644 --- a/script/deploy/devnet/deploy_from_scratch.s.sol +++ b/script/deploy/devnet/deploy_from_scratch.s.sol @@ -234,13 +234,12 @@ contract DeployFromScratch is Script, Test { // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegation, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegation, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegation, eigenLayerPauserReg ); @@ -492,10 +491,6 @@ contract DeployFromScratch is Script, Test { eigenPodManagerContract.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager: eigenPodBeacon contract address not set correctly" ); - require( - eigenPodManagerContract.strategyManager() == strategyManager, - "eigenPodManager: strategyManager contract address not set correctly" - ); require( rewardsCoordinatorContract.delegationManager() == delegation, diff --git a/script/deploy/local/Deploy_From_Scratch.s.sol b/script/deploy/local/Deploy_From_Scratch.s.sol index 53562144f..8987c680e 100644 --- a/script/deploy/local/Deploy_From_Scratch.s.sol +++ b/script/deploy/local/Deploy_From_Scratch.s.sol @@ -246,13 +246,12 @@ contract DeployFromScratch is Script, Test { // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegation, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegation, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegation, eigenLayerPauserReg ); @@ -499,10 +498,6 @@ contract DeployFromScratch is Script, Test { eigenPodManagerContract.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager: eigenPodBeacon contract address not set correctly" ); - require( - eigenPodManagerContract.strategyManager() == strategyManager, - "eigenPodManager: strategyManager contract address not set correctly" - ); require( rewardsCoordinatorContract.delegationManager() == delegation, diff --git a/script/deploy/local/deploy_from_scratch.slashing.s.sol b/script/deploy/local/deploy_from_scratch.slashing.s.sol index 2447ada29..38ba01b7d 100644 --- a/script/deploy/local/deploy_from_scratch.slashing.s.sol +++ b/script/deploy/local/deploy_from_scratch.slashing.s.sol @@ -241,13 +241,12 @@ contract DeployFromScratch is Script, Test { // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegation, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegation, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegation, eigenLayerPauserReg ); @@ -498,10 +497,6 @@ contract DeployFromScratch is Script, Test { eigenPodManagerContract.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager: eigenPodBeacon contract address not set correctly" ); - require( - eigenPodManagerContract.strategyManager() == strategyManager, - "eigenPodManager: strategyManager contract address not set correctly" - ); require( rewardsCoordinatorContract.delegationManager() == delegation, diff --git a/script/utils/ExistingDeploymentParser.sol b/script/utils/ExistingDeploymentParser.sol index 142fa331f..fcad17071 100644 --- a/script/utils/ExistingDeploymentParser.sol +++ b/script/utils/ExistingDeploymentParser.sol @@ -404,10 +404,6 @@ contract ExistingDeploymentParser is Script, Test { eigenPodManager.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager: eigenPodBeacon contract address not set correctly" ); - require( - eigenPodManager.strategyManager() == strategyManager, - "eigenPodManager: strategyManager contract address not set correctly" - ); require( eigenPodManager.delegationManager() == delegationManager, "eigenPodManager: delegationManager contract address not set correctly" diff --git a/src/contracts/core/AVSDirectoryStorage.sol b/src/contracts/core/AVSDirectoryStorage.sol index 9198d246f..0b9237a60 100644 --- a/src/contracts/core/AVSDirectoryStorage.sol +++ b/src/contracts/core/AVSDirectoryStorage.sol @@ -55,5 +55,5 @@ abstract contract AVSDirectoryStorage is IAVSDirectory { * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[41] private __gap; + uint256[47] private __gap; } diff --git a/src/contracts/core/AllocationManager.sol b/src/contracts/core/AllocationManager.sol index cbb4e6ff5..8e8fb2ac8 100644 --- a/src/contracts/core/AllocationManager.sol +++ b/src/contracts/core/AllocationManager.sol @@ -62,9 +62,9 @@ contract AllocationManager is ) external onlyWhenNotPaused(PAUSED_OPERATOR_SLASHING) checkCanCall(avs) { // Check that the operator set exists and the operator is registered to it OperatorSet memory operatorSet = OperatorSet(avs, params.operatorSetId); - bool isRegistered = _isRegistered(params.operator, operatorSet); + bool isOperatorSlashable = _isOperatorSlashable(params.operator, operatorSet); require(_operatorSets[operatorSet.avs].contains(operatorSet.id), InvalidOperatorSet()); - require(isRegistered, NotMemberOfSet()); + require(isOperatorSlashable, OperatorNotSlashable()); uint256[] memory wadSlashed = new uint256[](params.strategies.length); @@ -89,7 +89,7 @@ contract AllocationManager is // 2. Skip if the operator does not have a slashable allocation // NOTE: this "if" is equivalent to: `if (!_isAllocationSlashable)`, because the other - // conditions in this method are already true (isRegistered + operatorSetStrategies.contains) + // conditions in this method are already true (isOperatorSlashable + operatorSetStrategies.contains) if (allocation.currentMagnitude == 0) { continue; } @@ -165,7 +165,7 @@ contract AllocationManager is OperatorSet memory operatorSet = params[i].operatorSet; require(_operatorSets[operatorSet.avs].contains(operatorSet.id), InvalidOperatorSet()); - bool isRegistered = _isRegistered(operator, operatorSet); + bool isOperatorSlashable = _isOperatorSlashable(operator, operatorSet); for (uint256 j = 0; j < params[i].strategies.length; j++) { IStrategy strategy = params[i].strategies[j]; @@ -181,7 +181,7 @@ contract AllocationManager is // 2. Check whether the operator's allocation is slashable. If not, we allow instant // deallocation. - bool isSlashable = _isAllocationSlashable(operatorSet, strategy, allocation, isRegistered); + bool isSlashable = _isAllocationSlashable(operatorSet, strategy, allocation, isOperatorSlashable); // 3. Calculate the change in magnitude allocation.pendingDiff = _calcDelta(allocation.currentMagnitude, params[i].newMagnitudes[j]); @@ -242,7 +242,7 @@ contract AllocationManager is // Check the operator set exists and the operator is not currently registered to it OperatorSet memory operatorSet = OperatorSet(params.avs, params.operatorSetIds[i]); require(_operatorSets[operatorSet.avs].contains(operatorSet.id), InvalidOperatorSet()); - require(!_isRegistered(operator, operatorSet), AlreadyMemberOfSet()); + require(!_isOperatorSlashable(operator, operatorSet), AlreadyMemberOfSet()); // Add operator to operator set registeredSets[operator].add(operatorSet.key()); @@ -279,7 +279,7 @@ contract AllocationManager is // forgefmt: disable-next-item registrationStatus[params.operator][operatorSet.key()] = RegistrationStatus({ registered: false, - registeredUntil: uint32(block.number) + DEALLOCATION_DELAY + slashableUntil: uint32(block.number) + DEALLOCATION_DELAY }); } @@ -427,34 +427,28 @@ contract AllocationManager is emit AllocationDelaySet(operator, delay, info.effectBlock); } - function _isRegistered(address operator, OperatorSet memory operatorSet) internal view returns (bool) { + /// @notice returns whether the operator is slashable in the given operator set + function _isOperatorSlashable(address operator, OperatorSet memory operatorSet) internal view returns (bool) { RegistrationStatus memory status = registrationStatus[operator][operatorSet.key()]; - return status.registered || block.number < status.registeredUntil; + return status.registered || block.number < status.slashableUntil; } + /// @notice returns whether the operator's allocation is slashable in the given operator set function _isAllocationSlashable( OperatorSet memory operatorSet, IStrategy strategy, Allocation memory allocation, - bool isRegistered + bool isOperatorSlashable ) internal view returns (bool) { - // If the operator set does not use this strategy, any allocation from it is not slashable - if (!_operatorSetStrategies[operatorSet.key()].contains(address(strategy))) { - return false; - } - - // If the operator is not registered to the operator set, any allocation is not slashable - if (!isRegistered) { - return false; - } - - // The allocation is not slashable if there is nothing allocated - if (allocation.currentMagnitude == 0) { - return false; - } - - return true; + /// forgefmt: disable-next-item + return + // If the operator set does not use this strategy, any allocation from it is not slashable + _operatorSetStrategies[operatorSet.key()].contains(address(strategy)) && + // If the operator is not slashable by the operatorSet, any allocation is not slashable + isOperatorSlashable && + // If there is nothing allocated, the allocation is not slashable + allocation.currentMagnitude != 0; } /** @@ -738,6 +732,11 @@ contract AllocationManager is return operatorSets; } + /// @inheritdoc IAllocationManager + function isMemberOfOperatorSet(address operator, OperatorSet memory operatorSet) public view returns (bool) { + return _operatorSetMembers[operatorSet.key()].contains(operator); + } + /// @inheritdoc IAllocationManager function isOperatorSet( OperatorSet memory operatorSet diff --git a/src/contracts/core/DelegationManager.sol b/src/contracts/core/DelegationManager.sol index 968bd3197..b8747f3d2 100644 --- a/src/contracts/core/DelegationManager.sol +++ b/src/contracts/core/DelegationManager.sol @@ -64,7 +64,6 @@ contract DelegationManager is * @dev Initializes the immutable addresses of the strategy mananger, eigenpod manager, and allocation manager. */ constructor( - IAVSDirectory _avsDirectory, IStrategyManager _strategyManager, IEigenPodManager _eigenPodManager, IAllocationManager _allocationManager, @@ -72,13 +71,7 @@ contract DelegationManager is IPermissionController _permissionController, uint32 _MIN_WITHDRAWAL_DELAY ) - DelegationManagerStorage( - _avsDirectory, - _strategyManager, - _eigenPodManager, - _allocationManager, - _MIN_WITHDRAWAL_DELAY - ) + DelegationManagerStorage(_strategyManager, _eigenPodManager, _allocationManager, _MIN_WITHDRAWAL_DELAY) Pausable(_pauserRegistry) PermissionControllerMixin(_permissionController) { diff --git a/src/contracts/core/DelegationManagerStorage.sol b/src/contracts/core/DelegationManagerStorage.sol index d9066f85a..5d3f967bb 100644 --- a/src/contracts/core/DelegationManagerStorage.sol +++ b/src/contracts/core/DelegationManagerStorage.sol @@ -5,7 +5,6 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "../libraries/SlashingLib.sol"; import "../interfaces/IDelegationManager.sol"; -import "../interfaces/IAVSDirectory.sol"; import "../interfaces/IEigenPodManager.sol"; import "../interfaces/IAllocationManager.sol"; @@ -41,11 +40,6 @@ abstract contract DelegationManagerStorage is IDelegationManager { // Immutables - /// @notice The AVSDirectory contract for EigenLayer - IAVSDirectory public immutable avsDirectory; - - // TODO: Switch these to ShareManagers, but this breaks a lot of tests - /// @notice The StrategyManager contract for EigenLayer IStrategyManager public immutable strategyManager; @@ -124,13 +118,11 @@ abstract contract DelegationManagerStorage is IDelegationManager { // Construction constructor( - IAVSDirectory _avsDirectory, IStrategyManager _strategyManager, IEigenPodManager _eigenPodManager, IAllocationManager _allocationManager, uint32 _MIN_WITHDRAWAL_DELAY_BLOCKS ) { - avsDirectory = _avsDirectory; strategyManager = _strategyManager; eigenPodManager = _eigenPodManager; allocationManager = _allocationManager; diff --git a/src/contracts/interfaces/IAVSDirectory.sol b/src/contracts/interfaces/IAVSDirectory.sol index 231ef2e9d..5f3bf1696 100644 --- a/src/contracts/interfaces/IAVSDirectory.sol +++ b/src/contracts/interfaces/IAVSDirectory.sol @@ -14,19 +14,6 @@ interface IAVSDirectoryErrors { error OperatorNotRegisteredToAVS(); /// @dev Thrown when `operator` is already registered to the AVS. error OperatorAlreadyRegisteredToAVS(); - - /// @notice Enum representing the status of an operator's registration with an AVS - /// @dev Thrown when an invalid AVS is provided. - error InvalidAVS(); - /// @dev Thrown when an invalid operator is provided. - error InvalidOperator(); - /// @dev Thrown when an invalid operator set is provided. - error InvalidOperatorSet(); - /// @dev Thrown when a strategy is already added to an operator set. - error StrategyAlreadyInOperatorSet(); - /// @dev Thrown when a strategy is not in an operator set. - error StrategyNotInOperatorSet(); - /// @dev Thrown when attempting to spend a spent eip-712 salt. error SaltSpent(); } diff --git a/src/contracts/interfaces/IAllocationManager.sol b/src/contracts/interfaces/IAllocationManager.sol index 05ee9d117..4b41edfb1 100644 --- a/src/contracts/interfaces/IAllocationManager.sol +++ b/src/contracts/interfaces/IAllocationManager.sol @@ -14,8 +14,6 @@ interface IAllocationManagerErrors { error InvalidWadToSlash(); /// @dev Thrown when two array parameters have mismatching lengths. error InputArrayLengthMismatch(); - /// @dev Thrown when calling a view function that requires a valid block number. - error InvalidBlockNumber(); /// @dev Thrown when creating an operator set with more than max strategies. error MaxStrategiesExceeded(); @@ -43,13 +41,11 @@ interface IAllocationManagerErrors { /// @dev Thrown when an invalid operator set is provided. error InvalidOperatorSet(); - /// @dev Thrown when a strategy is referenced that does not belong to an operator set. - error InvalidStrategy(); /// @dev Thrown when provided `strategies` are not in ascending order. error StrategiesMustBeInAscendingOrder(); /// @dev Thrown when trying to add a strategy to an operator set that already contains it. error StrategyAlreadyInOperatorSet(); - /// @dev Thrown when trying to remove a strategy from an operator set it is not a part of. + /// @dev Thrown when a strategy is referenced that does not belong to an operator set. error StrategyNotInOperatorSet(); /// Modifying Allocations @@ -93,12 +89,12 @@ interface IAllocationManagerTypes { /** * @notice Contains registration details for an operator pertaining to an operator set * @param registered Whether the operator is currently registered for the operator set - * @param registeredUntil If the operator is not registered, how long until the operator is no longer + * @param slashableUntil If the operator is not registered, how long until the operator is no longer * slashable by the AVS. */ struct RegistrationStatus { bool registered; - uint32 registeredUntil; + uint32 slashableUntil; } /** @@ -485,6 +481,13 @@ interface IAllocationManager is ISignatureUtils, IAllocationManagerErrors, IAllo address operator ) external view returns (OperatorSet[] memory operatorSets); + /** + * @notice Returns whether the operator is registered for the operator set + * @param operator The operator to query + * @param operatorSet The operator set to query + */ + function isMemberOfOperatorSet(address operator, OperatorSet memory operatorSet) external view returns (bool); + /** * @notice Returns whether the operator set exists */ diff --git a/src/contracts/interfaces/IDelegationFaucet.sol b/src/contracts/interfaces/IDelegationFaucet.sol deleted file mode 100644 index 5642c1342..000000000 --- a/src/contracts/interfaces/IDelegationFaucet.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import "src/contracts/interfaces/IDelegationManager.sol"; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -interface IDelegationFaucet { - function mintDepositAndDelegate( - address _operator, - IDelegationManager.SignatureWithExpiry memory approverSignatureAndExpiry, - bytes32 approverSalt, - uint256 _depositAmount - ) external; - - function getStaker( - address operator - ) external returns (address); - - function depositIntoStrategy( - address staker, - IStrategy strategy, - IERC20 token, - uint256 amount - ) external returns (bytes memory); - - function queueWithdrawal( - address staker, - IDelegationManager.QueuedWithdrawalParams[] calldata queuedWithdrawalParams - ) external returns (bytes memory); - - function completeQueuedWithdrawal( - address staker, - IDelegationManager.Withdrawal calldata queuedWithdrawal, - IERC20[] calldata tokens, - uint256 middlewareTimesIndex, - bool receiveAsTokens - ) external returns (bytes memory); - - function transfer(address staker, address token, address to, uint256 amount) external returns (bytes memory); - - function callAddress(address to, bytes memory data) external payable returns (bytes memory); -} diff --git a/src/contracts/interfaces/IDelegationManager.sol b/src/contracts/interfaces/IDelegationManager.sol index a13a390b6..b43d9250c 100644 --- a/src/contracts/interfaces/IDelegationManager.sol +++ b/src/contracts/interfaces/IDelegationManager.sol @@ -7,8 +7,8 @@ import "./ISignatureUtils.sol"; import "../libraries/SlashingLib.sol"; interface IDelegationManagerErrors { - /// @dev Thrown when msg.sender is not allowed to call a function - error UnauthorizedCaller(); + /// @dev Thrown when caller is neither the StrategyManager or EigenPodManager contract. + error OnlyStrategyManagerOrEigenPodManager(); /// @dev Thrown when msg.sender is not the EigenPodManager error OnlyEigenPodManager(); /// @dev Throw when msg.sender is not the AllocationManager @@ -35,8 +35,6 @@ interface IDelegationManagerErrors { error InputArrayLengthMismatch(); /// @dev Thrown when input arrays length is zero. error InputArrayLengthZero(); - /// @dev Thrown when caller is neither the StrategyManager or EigenPodManager contract. - error OnlyStrategyManagerOrEigenPodManager(); /// Slashing @@ -51,12 +49,8 @@ interface IDelegationManagerErrors { /// Withdrawal Processing - /// @dev Thrown when attempting to execute an action that was not queued. - error WithdrawalDoesNotExist(); /// @dev Thrown when attempting to withdraw before delay has elapsed. error WithdrawalDelayNotElapsed(); - /// @dev Thrown when provided delay exceeds maximum. - error WithdrawalDelayExeedsMax(); /// @dev Thrown when a withdraw amount larger than max is attempted. error WithdrawalExceedsMax(); /// @dev Thrown when withdrawer is not the current caller. diff --git a/src/contracts/interfaces/IEigenPodManager.sol b/src/contracts/interfaces/IEigenPodManager.sol index dfc46219b..32a749fa3 100644 --- a/src/contracts/interfaces/IEigenPodManager.sol +++ b/src/contracts/interfaces/IEigenPodManager.sol @@ -129,9 +129,6 @@ interface IEigenPodManager is /// @notice Beacon proxy to which the EigenPods point function eigenPodBeacon() external view returns (IBeacon); - /// @notice EigenLayer's StrategyManager contract - function strategyManager() external view returns (IStrategyManager); - /// @notice Returns 'true' if the `podOwner` has created an EigenPod, and 'false' otherwise. function hasPod( address podOwner diff --git a/src/contracts/interfaces/ISlasher.sol b/src/contracts/interfaces/ISlasher.sol deleted file mode 100644 index 1cd77b996..000000000 --- a/src/contracts/interfaces/ISlasher.sol +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity >=0.5.0; - -import "./IStrategyManager.sol"; -import "./IDelegationManager.sol"; - -/** - * @title Interface for the primary 'slashing' contract for EigenLayer. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice See the `Slasher` contract itself for implementation details. - */ -interface ISlasher { - // struct used to store information about the current state of an operator's obligations to middlewares they are serving - struct MiddlewareTimes { - // The update block for the middleware whose most recent update was earliest, i.e. the 'stalest' update out of all middlewares the operator is serving - uint32 stalestUpdateBlock; - // The latest 'serveUntilBlock' from all of the middleware that the operator is serving - uint32 latestServeUntilBlock; - } - - // struct used to store details relevant to a single middleware that an operator has opted-in to serving - struct MiddlewareDetails { - // the block at which the contract begins being able to finalize the operator's registration with the service via calling `recordFirstStakeUpdate` - uint32 registrationMayBeginAtBlock; - // the block before which the contract is allowed to slash the user - uint32 contractCanSlashOperatorUntilBlock; - // the block at which the middleware's view of the operator's stake was most recently updated - uint32 latestUpdateBlock; - } - - /// @notice Emitted when a middleware times is added to `operator`'s array. - event MiddlewareTimesAdded( - address operator, uint256 index, uint32 stalestUpdateBlock, uint32 latestServeUntilBlock - ); - - /// @notice Emitted when `operator` begins to allow `contractAddress` to slash them. - event OptedIntoSlashing(address indexed operator, address indexed contractAddress); - - /// @notice Emitted when `contractAddress` signals that it will no longer be able to slash `operator` after the `contractCanSlashOperatorUntilBlock`. - event SlashingAbilityRevoked( - address indexed operator, address indexed contractAddress, uint32 contractCanSlashOperatorUntilBlock - ); - - /** - * @notice Emitted when `slashingContract` 'freezes' the `slashedOperator`. - * @dev The `slashingContract` must have permission to slash the `slashedOperator`, i.e. `canSlash(slasherOperator, slashingContract)` must return 'true'. - */ - event OperatorFrozen(address indexed slashedOperator, address indexed slashingContract); - - /// @notice Emitted when `previouslySlashedAddress` is 'unfrozen', allowing them to again move deposited funds within EigenLayer. - event FrozenStatusReset(address indexed previouslySlashedAddress); - - /** - * @notice Gives the `contractAddress` permission to slash the funds of the caller. - * @dev Typically, this function must be called prior to registering for a middleware. - */ - function optIntoSlashing( - address contractAddress - ) external; - - /** - * @notice Used for 'slashing' a certain operator. - * @param toBeFrozen The operator to be frozen. - * @dev Technically the operator is 'frozen' (hence the name of this function), and then subject to slashing pending a decision by a human-in-the-loop. - * @dev The operator must have previously given the caller (which should be a contract) the ability to slash them, through a call to `optIntoSlashing`. - */ - function freezeOperator( - address toBeFrozen - ) external; - - /** - * @notice Removes the 'frozen' status from each of the `frozenAddresses` - * @dev Callable only by the contract owner (i.e. governance). - */ - function resetFrozenStatus( - address[] calldata frozenAddresses - ) external; - - /** - * @notice this function is a called by middlewares during an operator's registration to make sure the operator's stake at registration - * is slashable until serveUntil - * @param operator the operator whose stake update is being recorded - * @param serveUntilBlock the block until which the operator's stake at the current block is slashable - * @dev adds the middleware's slashing contract to the operator's linked list - */ - function recordFirstStakeUpdate(address operator, uint32 serveUntilBlock) external; - - /** - * @notice this function is a called by middlewares during a stake update for an operator (perhaps to free pending withdrawals) - * to make sure the operator's stake at updateBlock is slashable until serveUntil - * @param operator the operator whose stake update is being recorded - * @param updateBlock the block for which the stake update is being recorded - * @param serveUntilBlock the block until which the operator's stake at updateBlock is slashable - * @param insertAfter the element of the operators linked list that the currently updating middleware should be inserted after - * @dev insertAfter should be calculated offchain before making the transaction that calls this. this is subject to race conditions, - * but it is anticipated to be rare and not detrimental. - */ - function recordStakeUpdate( - address operator, - uint32 updateBlock, - uint32 serveUntilBlock, - uint256 insertAfter - ) external; - - /** - * @notice this function is a called by middlewares during an operator's deregistration to make sure the operator's stake at deregistration - * is slashable until serveUntil - * @param operator the operator whose stake update is being recorded - * @param serveUntilBlock the block until which the operator's stake at the current block is slashable - * @dev removes the middleware's slashing contract to the operator's linked list and revokes the middleware's (i.e. caller's) ability to - * slash `operator` once `serveUntil` is reached - */ - function recordLastStakeUpdateAndRevokeSlashingAbility(address operator, uint32 serveUntilBlock) external; - - /// @notice The StrategyManager contract of EigenLayer - function strategyManager() external view returns (IStrategyManager); - - /// @notice The DelegationManager contract of EigenLayer - function delegation() external view returns (IDelegationManager); - - /** - * @notice Used to determine whether `staker` is actively 'frozen'. If a staker is frozen, then they are potentially subject to - * slashing of their funds, and cannot cannot deposit or withdraw from the strategyManager until the slashing process is completed - * and the staker's status is reset (to 'unfrozen'). - * @param staker The staker of interest. - * @return Returns 'true' if `staker` themselves has their status set to frozen, OR if the staker is delegated - * to an operator who has their status set to frozen. Otherwise returns 'false'. - */ - function isFrozen( - address staker - ) external view returns (bool); - - /// @notice Returns true if `slashingContract` is currently allowed to slash `toBeSlashed`. - function canSlash(address toBeSlashed, address slashingContract) external view returns (bool); - - /// @notice Returns the block until which `serviceContract` is allowed to slash the `operator`. - function contractCanSlashOperatorUntilBlock( - address operator, - address serviceContract - ) external view returns (uint32); - - /// @notice Returns the block at which the `serviceContract` last updated its view of the `operator`'s stake - function latestUpdateBlock(address operator, address serviceContract) external view returns (uint32); - - /// @notice A search routine for finding the correct input value of `insertAfter` to `recordStakeUpdate` / `_updateMiddlewareList`. - function getCorrectValueForInsertAfter(address operator, uint32 updateBlock) external view returns (uint256); - - /** - * @notice Returns 'true' if `operator` can currently complete a withdrawal started at the `withdrawalStartBlock`, with `middlewareTimesIndex` used - * to specify the index of a `MiddlewareTimes` struct in the operator's list (i.e. an index in `operatorToMiddlewareTimes[operator]`). The specified - * struct is consulted as proof of the `operator`'s ability (or lack thereof) to complete the withdrawal. - * This function will return 'false' if the operator cannot currently complete a withdrawal started at the `withdrawalStartBlock`, *or* in the event - * that an incorrect `middlewareTimesIndex` is supplied, even if one or more correct inputs exist. - * @param operator Either the operator who queued the withdrawal themselves, or if the withdrawing party is a staker who delegated to an operator, - * this address is the operator *who the staker was delegated to* at the time of the `withdrawalStartBlock`. - * @param withdrawalStartBlock The block number at which the withdrawal was initiated. - * @param middlewareTimesIndex Indicates an index in `operatorToMiddlewareTimes[operator]` to consult as proof of the `operator`'s ability to withdraw - * @dev The correct `middlewareTimesIndex` input should be computable off-chain. - */ - function canWithdraw( - address operator, - uint32 withdrawalStartBlock, - uint256 middlewareTimesIndex - ) external returns (bool); - - /** - * operator => - * [ - * ( - * the least recent update block of all of the middlewares it's serving/served, - * latest time that the stake bonded at that update needed to serve until - * ) - * ] - */ - function operatorToMiddlewareTimes( - address operator, - uint256 arrayIndex - ) external view returns (MiddlewareTimes memory); - - /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator].length` - function middlewareTimesLength( - address operator - ) external view returns (uint256); - - /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator][index].stalestUpdateBlock`. - function getMiddlewareTimesIndexStalestUpdateBlock(address operator, uint32 index) external view returns (uint32); - - /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator][index].latestServeUntil`. - function getMiddlewareTimesIndexServeUntilBlock(address operator, uint32 index) external view returns (uint32); - - /// @notice Getter function for fetching `_operatorToWhitelistedContractsByUpdate[operator].size`. - function operatorWhitelistedContractsLinkedListSize( - address operator - ) external view returns (uint256); - - /// @notice Getter function for fetching a single node in the operator's linked list (`_operatorToWhitelistedContractsByUpdate[operator]`). - function operatorWhitelistedContractsLinkedListEntry( - address operator, - address node - ) external view returns (bool, uint256, uint256); -} diff --git a/src/contracts/interfaces/ISocketUpdater.sol b/src/contracts/interfaces/ISocketUpdater.sol deleted file mode 100644 index 921b1a46b..000000000 --- a/src/contracts/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/contracts/interfaces/IStrategyManager.sol b/src/contracts/interfaces/IStrategyManager.sol index da5d0a813..7a2d0c38d 100644 --- a/src/contracts/interfaces/IStrategyManager.sol +++ b/src/contracts/interfaces/IStrategyManager.sol @@ -9,8 +9,6 @@ import "./IEigenPodManager.sol"; interface IStrategyManagerErrors { /// @dev Thrown when total strategies deployed exceeds max. error MaxStrategiesExceeded(); - /// @dev Thrown when two array parameters have mismatching lengths. - error InputArrayLengthMismatch(); /// @dev Thrown when call attempted from address that's not delegation manager. error OnlyDelegationManager(); /// @dev Thrown when call attempted from address that's not strategy whitelister. diff --git a/src/contracts/pods/EigenPodManager.sol b/src/contracts/pods/EigenPodManager.sol index 418cdd003..46e12779f 100644 --- a/src/contracts/pods/EigenPodManager.sol +++ b/src/contracts/pods/EigenPodManager.sol @@ -46,13 +46,9 @@ contract EigenPodManager is constructor( IETHPOSDeposit _ethPOS, IBeacon _eigenPodBeacon, - IStrategyManager _strategyManager, IDelegationManager _delegationManager, IPauserRegistry _pauserRegistry - ) - EigenPodManagerStorage(_ethPOS, _eigenPodBeacon, _strategyManager, _delegationManager) - Pausable(_pauserRegistry) - { + ) EigenPodManagerStorage(_ethPOS, _eigenPodBeacon, _delegationManager) Pausable(_pauserRegistry) { _disableInitializers(); } diff --git a/src/contracts/pods/EigenPodManagerStorage.sol b/src/contracts/pods/EigenPodManagerStorage.sol index bda301349..c02d63bcc 100644 --- a/src/contracts/pods/EigenPodManagerStorage.sol +++ b/src/contracts/pods/EigenPodManagerStorage.sol @@ -23,9 +23,6 @@ abstract contract EigenPodManagerStorage is IEigenPodManager { /// @notice Beacon proxy to which the EigenPods point IBeacon public immutable eigenPodBeacon; - /// @notice EigenLayer's StrategyManager contract - IStrategyManager public immutable strategyManager; - /// @notice EigenLayer's DelegationManager contract IDelegationManager public immutable delegationManager; @@ -81,15 +78,9 @@ abstract contract EigenPodManagerStorage is IEigenPodManager { /// Note: this is specifically updated when the staker's beacon chain balance decreases mapping(address staker => BeaconChainSlashingFactor) internal _beaconChainSlashingFactor; - constructor( - IETHPOSDeposit _ethPOS, - IBeacon _eigenPodBeacon, - IStrategyManager _strategyManager, - IDelegationManager _delegationManager - ) { + constructor(IETHPOSDeposit _ethPOS, IBeacon _eigenPodBeacon, IDelegationManager _delegationManager) { ethPOS = _ethPOS; eigenPodBeacon = _eigenPodBeacon; - strategyManager = _strategyManager; delegationManager = _delegationManager; } diff --git a/src/test/harnesses/EigenPodManagerWrapper.sol b/src/test/harnesses/EigenPodManagerWrapper.sol index 9e9db1ce9..ffb190a55 100644 --- a/src/test/harnesses/EigenPodManagerWrapper.sol +++ b/src/test/harnesses/EigenPodManagerWrapper.sol @@ -8,10 +8,9 @@ contract EigenPodManagerWrapper is EigenPodManager { constructor( IETHPOSDeposit _ethPOS, IBeacon _eigenPodBeacon, - IStrategyManager _strategyManager, IDelegationManager _delegationManager, IPauserRegistry _pauserRegistry - ) EigenPodManager(_ethPOS, _eigenPodBeacon, _strategyManager, _delegationManager, _pauserRegistry) {} + ) EigenPodManager(_ethPOS, _eigenPodBeacon, _delegationManager, _pauserRegistry) {} function setPodOwnerShares(address owner, IEigenPod pod) external { ownerToPod[owner] = pod; diff --git a/src/test/integration/IntegrationDeployer.t.sol b/src/test/integration/IntegrationDeployer.t.sol index 0c9509923..0f6a36909 100644 --- a/src/test/integration/IntegrationDeployer.t.sol +++ b/src/test/integration/IntegrationDeployer.t.sol @@ -195,18 +195,16 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser, Logger { eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationManagerImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationManagerImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegationManager, eigenLayerPauserReg ); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); - eigenPodManagerImplementation = - new EigenPodManager(ethPOSDeposit, eigenPodBeacon, strategyManager, delegationManager, eigenLayerPauserReg); + eigenPodManagerImplementation = new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegationManager, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegationManager, eigenLayerPauserReg); strategyFactoryImplementation = new StrategyFactory(strategyManager, eigenLayerPauserReg); allocationManagerImplementation = new AllocationManager(delegationManager, eigenLayerPauserReg, permissionController, DEALLOCATION_DELAY, ALLOCATION_CONFIGURATION_DELAY); @@ -332,18 +330,16 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser, Logger { ); // First, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationManagerImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationManagerImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegationManager, eigenLayerPauserReg ); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); - eigenPodManagerImplementation = - new EigenPodManager(ethPOSDeposit, eigenPodBeacon, strategyManager, delegationManager, eigenLayerPauserReg); + eigenPodManagerImplementation = new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegationManager, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegationManager, eigenLayerPauserReg); // Second, upgrade the proxy contracts to point to the implementations @@ -415,18 +411,16 @@ abstract contract IntegrationDeployer is ExistingDeploymentParser, Logger { ); // First, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationManagerImplementation = new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); + delegationManagerImplementation = new DelegationManager(strategyManager, eigenPodManager, allocationManager, eigenLayerPauserReg, permissionController, MIN_WITHDRAWAL_DELAY); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, - strategyManager, delegationManager, eigenLayerPauserReg ); strategyManagerImplementation = new StrategyManager(delegationManager, eigenLayerPauserReg); - eigenPodManagerImplementation = - new EigenPodManager(ethPOSDeposit, eigenPodBeacon, strategyManager, delegationManager, eigenLayerPauserReg); + eigenPodManagerImplementation = new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegationManager, eigenLayerPauserReg); avsDirectoryImplementation = new AVSDirectory(delegationManager, eigenLayerPauserReg); // Second, upgrade the proxy contracts to point to the implementations diff --git a/src/test/integration/tests/Upgrade_Setup.t.sol b/src/test/integration/tests/Upgrade_Setup.t.sol index e33921c34..6bea40449 100644 --- a/src/test/integration/tests/Upgrade_Setup.t.sol +++ b/src/test/integration/tests/Upgrade_Setup.t.sol @@ -86,10 +86,6 @@ contract IntegrationMainnetFork_UpgradeSetup is IntegrationCheckUtils { eigenPodManager.eigenPodBeacon() == eigenPodBeacon, "eigenPodManager: eigenPodBeacon contract address not set correctly" ); - require( - eigenPodManager.strategyManager() == strategyManager, - "eigenPodManager: strategyManager contract address not set correctly" - ); require( eigenPodManager.delegationManager() == delegationManager, "eigenPodManager: delegationManager contract address not set correctly" diff --git a/src/test/unit/AllocationManagerUnit.t.sol b/src/test/unit/AllocationManagerUnit.t.sol index cfb6b0026..edf7f8c43 100644 --- a/src/test/unit/AllocationManagerUnit.t.sol +++ b/src/test/unit/AllocationManagerUnit.t.sol @@ -475,7 +475,7 @@ contract AllocationManagerUnitTests_SlashOperator is AllocationManagerUnitTests function test_revert_NotMemberOfSet() public { cheats.prank(defaultAVS); - cheats.expectRevert(NotMemberOfSet.selector); + cheats.expectRevert(OperatorNotSlashable.selector); allocationManager.slashOperator(defaultAVS, _randSlashingParams(random().Address(), 0)); } @@ -3048,6 +3048,11 @@ contract AllocationManagerUnitTests_registerForOperatorSets is AllocationManager assertEq(allocationManager.getRegisteredSets(operator).length, numOpSets, "should be registered for all sets"); for (uint256 k; k < numOpSets; ++k) { + OperatorSet memory operatorSet = OperatorSet(defaultAVS, operatorSetIds[k]); + assertTrue( + allocationManager.isMemberOfOperatorSet(operator, operatorSet), + "should be member of set" + ); assertEq( allocationManager.getMembers(OperatorSet(defaultAVS, operatorSetIds[k]))[0], operator, @@ -3144,6 +3149,10 @@ contract AllocationManagerUnitTests_deregisterFromOperatorSets is AllocationMana assertEq(allocationManager.getRegisteredSets(operator).length, 0, "should not be registered for any sets"); for (uint256 k; k < numOpSets; ++k) { + assertFalse( + allocationManager.isMemberOfOperatorSet(operator, OperatorSet(defaultAVS, operatorSetIds[k])), + "should not be member of set" + ); assertEq( allocationManager.getMemberCount(OperatorSet(defaultAVS, operatorSetIds[k])), 0, diff --git a/src/test/unit/DelegationUnit.t.sol b/src/test/unit/DelegationUnit.t.sol index 7baa2e4c6..ca0f94980 100644 --- a/src/test/unit/DelegationUnit.t.sol +++ b/src/test/unit/DelegationUnit.t.sol @@ -104,7 +104,6 @@ contract DelegationManagerUnitTests is EigenLayerUnitTestSetup, IDelegationManag // Deploy DelegationManager implmentation and upgrade proxy delegationManagerImplementation = new DelegationManager( - IAVSDirectory(address(avsDirectoryMock)), IStrategyManager(address(strategyManagerMock)), IEigenPodManager(address(eigenPodManagerMock)), IAllocationManager(address(allocationManagerMock)), diff --git a/src/test/unit/EigenPodManagerUnit.t.sol b/src/test/unit/EigenPodManagerUnit.t.sol index 4f9bd7b18..72befd4fd 100644 --- a/src/test/unit/EigenPodManagerUnit.t.sol +++ b/src/test/unit/EigenPodManagerUnit.t.sol @@ -43,7 +43,6 @@ contract EigenPodManagerUnitTests is EigenLayerUnitTestSetup, IEigenPodManagerEv eigenPodManagerImplementation = new EigenPodManager( ethPOSMock, eigenPodBeacon, - IStrategyManager(address(strategyManagerMock)), IDelegationManager(address(delegationManagerMock)), pauserRegistry ); @@ -119,7 +118,6 @@ contract EigenPodManagerUnitTests_Initialization_Setters is EigenPodManagerUnitT // Check storage variables assertEq(address(eigenPodManager.ethPOS()), address(ethPOSMock), "Initialization: ethPOS incorrect"); assertEq(address(eigenPodManager.eigenPodBeacon()), address(eigenPodBeacon), "Initialization: eigenPodBeacon incorrect"); - assertEq(address(eigenPodManager.strategyManager()), address(strategyManagerMock), "Initialization: strategyManager incorrect"); assertEq(address(eigenPodManager.delegationManager()), address(delegationManagerMock), "Initialization: delegationManager incorrect"); } @@ -305,7 +303,6 @@ contract EigenPodManagerUnitTests_WithdrawSharesAsTokensTests is EigenPodManager eigenPodManagerWrapper = new EigenPodManagerWrapper( ethPOSMock, eigenPodBeacon, - IStrategyManager(address(strategyManagerMock)), IDelegationManager(address(delegationManagerMock)), pauserRegistry ); @@ -428,7 +425,6 @@ contract EigenPodManagerUnitTests_BeaconChainETHBalanceUpdateTests is EigenPodMa eigenPodManagerWrapper = new EigenPodManagerWrapper( ethPOSMock, eigenPodBeacon, - IStrategyManager(address(strategyManagerMock)), IDelegationManager(address(delegationManagerMock)), pauserRegistry ); diff --git a/src/test/unit/PermissionControllerUnit.t.sol b/src/test/unit/PermissionControllerUnit.t.sol index 43088a4a3..5226a9d05 100644 --- a/src/test/unit/PermissionControllerUnit.t.sol +++ b/src/test/unit/PermissionControllerUnit.t.sol @@ -388,7 +388,7 @@ contract PermissionControllerUnitTests_RemoveAppointee is PermissionControllerUn } // Tests that the encoding from adding an appointee is properly decoded - function test_symmetricalTargetSelector() public { + function test_symmetricalTargetSelector() public view { // Test Decoding (address[] memory targets, bytes4[] memory selectors) = permissionController.getAppointeePermissions(account, appointee2); assertEq(targets.length, 1, "Incorrect number of targets");