diff --git a/docs/slashing/VetoableSlasher.md b/docs/slashing/VetoableSlasher.md index 20cfe8efd..5f2f19411 100644 --- a/docs/slashing/VetoableSlasher.md +++ b/docs/slashing/VetoableSlasher.md @@ -44,7 +44,7 @@ Creates and queues a new slashing request that will be executable after the veto #### `cancelSlashingRequest` ```solidity function cancelSlashingRequest( - uint256 requestId + uint256 slashId ) external virtual @@ -68,7 +68,7 @@ Allows the veto committee to cancel a pending slashing request within the veto w #### `fulfillSlashingRequest` ```solidity function fulfillSlashingRequest( - uint256 requestId + uint256 slashId ) external virtual diff --git a/lib/eigenlayer-contracts b/lib/eigenlayer-contracts index 9a9707b28..5dbb48339 160000 --- a/lib/eigenlayer-contracts +++ b/lib/eigenlayer-contracts @@ -1 +1 @@ -Subproject commit 9a9707b28fa6acbd512d8983ad7a71d7ecb222ad +Subproject commit 5dbb48339aeef41e11d65c8816f9489e53573fad diff --git a/src/interfaces/ISlasher.sol b/src/interfaces/ISlasher.sol index 7785b5376..ab9620a96 100644 --- a/src/interfaces/ISlasher.sol +++ b/src/interfaces/ISlasher.sol @@ -20,7 +20,7 @@ interface ISlasherTypes { interface ISlasherEvents is ISlasherTypes { /// @notice Emitted when an operator is successfully slashed event OperatorSlashed( - uint256 indexed slashingRequestId, + uint256 indexed slashId, address indexed operator, uint32 indexed operatorSetId, uint256[] wadsToSlash, @@ -33,7 +33,4 @@ interface ISlasherEvents is ISlasherTypes { interface ISlasher is ISlasherErrors, ISlasherEvents { /// @notice Returns the address authorized to create and fulfill slashing requests function slasher() external view returns (address); - - /// @notice Returns the next slashing request ID - function nextRequestId() external view returns (uint256); } diff --git a/src/interfaces/IVetoableSlasher.sol b/src/interfaces/IVetoableSlasher.sol index 796b42657..ec2eeb4c5 100644 --- a/src/interfaces/IVetoableSlasher.sol +++ b/src/interfaces/IVetoableSlasher.sol @@ -37,7 +37,7 @@ interface IVetoableSlasherTypes { interface IVetoableSlasherEvents { /// @notice Emitted when a new slashing request is created event SlashingRequested( - uint256 indexed requestId, + uint256 indexed slashId, address indexed operator, uint32 operatorSetId, uint256[] wadsToSlash, @@ -45,7 +45,7 @@ interface IVetoableSlasherEvents { ); /// @notice Emitted when a slashing request is cancelled by the veto committee - event SlashingRequestCancelled(uint256 indexed requestId); + event SlashingRequestCancelled(uint256 indexed slashId); } /// @title IVetoableSlasher @@ -71,16 +71,16 @@ interface IVetoableSlasher is ) external; /// @notice Cancels a pending slashing request - /// @param requestId The ID of the slashing request to cancel + /// @param slashId The ID of the slashing request to cancel /// @dev Can only be called by the veto committee during the veto period function cancelSlashingRequest( - uint256 requestId + uint256 slashId ) external; /// @notice Executes a slashing request after the veto period has passed - /// @param requestId The ID of the slashing request to fulfill + /// @param slashId The ID of the slashing request to fulfill /// @dev Can only be called by the authorized slasher after the veto period function fulfillSlashingRequest( - uint256 requestId + uint256 slashId ) external; } diff --git a/src/slashers/InstantSlasher.sol b/src/slashers/InstantSlasher.sol index c2de162c9..94d2b7a4e 100644 --- a/src/slashers/InstantSlasher.sol +++ b/src/slashers/InstantSlasher.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.27; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {SlasherBase} from "./base/SlasherBase.sol"; import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol"; import {IInstantSlasher} from "../interfaces/IInstantSlasher.sol"; @@ -14,19 +15,16 @@ import {IInstantSlasher} from "../interfaces/IInstantSlasher.sol"; contract InstantSlasher is IInstantSlasher, SlasherBase { constructor( IAllocationManager _allocationManager, + IStrategyManager _strategyManager, ISlashingRegistryCoordinator _slashingRegistryCoordinator, address _slasher - ) SlasherBase(_allocationManager, _slashingRegistryCoordinator, _slasher) {} + ) SlasherBase(_allocationManager, _strategyManager, _slashingRegistryCoordinator, _slasher) {} /// @inheritdoc IInstantSlasher function fulfillSlashingRequest( IAllocationManager.SlashingParams calldata _slashingParams ) external virtual override(IInstantSlasher) onlySlasher { - uint256 requestId = nextRequestId++; - _fulfillSlashingRequest(requestId, _slashingParams); - - address[] memory operators = new address[](1); - operators[0] = _slashingParams.operator; - slashingRegistryCoordinator.updateOperators(operators); + _fulfillSlashingRequest(_slashingParams); + _updateOperatorStakeWeights(_slashingParams.operator); } } diff --git a/src/slashers/VetoableSlasher.sol b/src/slashers/VetoableSlasher.sol index 58005226c..9c8a690fe 100644 --- a/src/slashers/VetoableSlasher.sol +++ b/src/slashers/VetoableSlasher.sol @@ -2,8 +2,11 @@ pragma solidity ^0.8.27; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; -import {IAllocationManager} from - "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import { + IAllocationManager, + OperatorSet +} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {SlasherBase} from "./base/SlasherBase.sol"; import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol"; import {IVetoableSlasher, IVetoableSlasherTypes} from "../interfaces/IVetoableSlasher.sol"; @@ -29,11 +32,12 @@ contract VetoableSlasher is IVetoableSlasher, SlasherBase { constructor( IAllocationManager _allocationManager, + IStrategyManager _strategyManager, ISlashingRegistryCoordinator _slashingRegistryCoordinator, address _slasher, address _vetoCommittee, uint32 _vetoWindowBlocks - ) SlasherBase(_allocationManager, _slashingRegistryCoordinator, _slasher) { + ) SlasherBase(_allocationManager, _strategyManager, _slashingRegistryCoordinator, _slasher) { vetoWindowBlocks = _vetoWindowBlocks; vetoCommittee = _vetoCommittee; } @@ -47,16 +51,16 @@ contract VetoableSlasher is IVetoableSlasher, SlasherBase { /// @inheritdoc IVetoableSlasher function cancelSlashingRequest( - uint256 requestId + uint256 slashId ) external virtual override onlyVetoCommittee { - _cancelSlashingRequest(requestId); + _cancelSlashingRequest(slashId); } /// @inheritdoc IVetoableSlasher function fulfillSlashingRequest( - uint256 requestId + uint256 slashId ) external virtual override onlySlasher { - _fulfillSlashingRequestAndMarkAsCompleted(requestId); + _fulfillSlashingRequestAndMarkAsCompleted(slashId); } /// @notice Internal function to create and store a new slashing request @@ -64,42 +68,48 @@ contract VetoableSlasher is IVetoableSlasher, SlasherBase { function _queueSlashingRequest( IAllocationManager.SlashingParams memory params ) internal virtual { - uint256 requestId = nextRequestId++; - slashingRequests[requestId] = IVetoableSlasherTypes.VetoableSlashingRequest({ + uint256 nextSlashId = allocationManager.getSlashCount( + OperatorSet({avs: slashingRegistryCoordinator.avs(), id: params.operatorSetId}) + ); + slashingRequests[nextSlashId] = IVetoableSlasherTypes.VetoableSlashingRequest({ params: params, requestBlock: block.number, status: IVetoableSlasherTypes.SlashingStatus.Requested }); emit SlashingRequested( - requestId, params.operator, params.operatorSetId, params.wadsToSlash, params.description + nextSlashId, + params.operator, + params.operatorSetId, + params.wadsToSlash, + params.description ); } /// @notice Internal function to mark a slashing request as cancelled - /// @param requestId The ID of the slashing request to cancel + /// @param slashId The ID of the slashing request to cancel function _cancelSlashingRequest( - uint256 requestId + uint256 slashId ) internal virtual { require( - block.number < slashingRequests[requestId].requestBlock + vetoWindowBlocks, + block.number < slashingRequests[slashId].requestBlock + vetoWindowBlocks, VetoPeriodPassed() ); require( - slashingRequests[requestId].status == IVetoableSlasherTypes.SlashingStatus.Requested, + slashingRequests[slashId].status == IVetoableSlasherTypes.SlashingStatus.Requested, SlashingRequestNotRequested() ); - slashingRequests[requestId].status = IVetoableSlasherTypes.SlashingStatus.Cancelled; - emit SlashingRequestCancelled(requestId); + slashingRequests[slashId].status = IVetoableSlasherTypes.SlashingStatus.Cancelled; + emit SlashingRequestCancelled(slashId); } /// @notice Internal function to fulfill a slashing request and mark it as completed - /// @param requestId The ID of the slashing request to fulfill + /// @param slashId The ID of the slashing request to fulfill function _fulfillSlashingRequestAndMarkAsCompleted( - uint256 requestId + uint256 slashId ) internal virtual { - IVetoableSlasherTypes.VetoableSlashingRequest storage request = slashingRequests[requestId]; + IVetoableSlasherTypes.VetoableSlashingRequest storage request = slashingRequests[slashId]; require(block.number >= request.requestBlock + vetoWindowBlocks, VetoPeriodNotPassed()); require( request.status == IVetoableSlasherTypes.SlashingStatus.Requested, @@ -108,11 +118,8 @@ contract VetoableSlasher is IVetoableSlasher, SlasherBase { request.status = IVetoableSlasherTypes.SlashingStatus.Completed; - _fulfillSlashingRequest(requestId, request.params); - - address[] memory operators = new address[](1); - operators[0] = request.params.operator; - slashingRegistryCoordinator.updateOperators(operators); + _fulfillSlashingRequest(request.params); + _updateOperatorStakeWeights(request.params.operator); } /// @notice Internal function to verify if an account is the veto committee diff --git a/src/slashers/base/SlasherBase.sol b/src/slashers/base/SlasherBase.sol index c0f74b937..4a27385dc 100644 --- a/src/slashers/base/SlasherBase.sol +++ b/src/slashers/base/SlasherBase.sol @@ -3,9 +3,11 @@ pragma solidity ^0.8.27; import {SlasherStorage, ISlashingRegistryCoordinator} from "./SlasherStorage.sol"; import { + OperatorSet, IAllocationManagerTypes, IAllocationManager } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; /// @title SlasherBase @@ -24,21 +26,23 @@ abstract contract SlasherBase is SlasherStorage { /// @param _slasher The address of the slasher constructor( IAllocationManager _allocationManager, + IStrategyManager _strategyManager, ISlashingRegistryCoordinator _registryCoordinator, address _slasher - ) SlasherStorage(_allocationManager, _registryCoordinator, _slasher) {} + ) SlasherStorage(_allocationManager, _strategyManager, _registryCoordinator, _slasher) {} /// @notice Internal function to execute a slashing request - /// @param _requestId The ID of the slashing request to fulfill /// @param _params Parameters defining the slashing request including operator, strategies, and amounts /// @dev Calls AllocationManager.slashOperator to perform the actual slashing function _fulfillSlashingRequest( - uint256 _requestId, IAllocationManager.SlashingParams memory _params - ) internal virtual { - allocationManager.slashOperator({avs: slashingRegistryCoordinator.avs(), params: _params}); + ) internal virtual returns (uint256 slashId) { + (slashId,) = allocationManager.slashOperator({ + avs: slashingRegistryCoordinator.avs(), + params: _params + }); emit OperatorSlashed( - _requestId, + slashId, _params.operator, _params.operatorSetId, _params.wadsToSlash, @@ -46,6 +50,22 @@ abstract contract SlasherBase is SlasherStorage { ); } + /// @notice Internal function to optionally fulfill burn or redistribution instead of waiting for cron job + function _fulfillBurnOrRedistribution(uint32 operatorSetId, uint256 slashId) internal virtual { + strategyManager.clearBurnOrRedistributableShares({ + operatorSet: OperatorSet({avs: slashingRegistryCoordinator.avs(), id: operatorSetId}), + slashId: slashId + }); + } + + /// @notice Internal function to fulfill a slashing request and burn or redistribute shares + function _fulfillSlashingRequestAndBurnOrRedistribute( + IAllocationManager.SlashingParams memory _params + ) internal virtual returns (uint256 slashId) { + slashId = _fulfillSlashingRequest(_params); + _fulfillBurnOrRedistribution(_params.operatorSetId, slashId); + } + /// @notice Internal function to verify if an account is the authorized slasher /// @param account The address to check /// @dev Reverts if the account is not the authorized slasher @@ -54,4 +74,14 @@ abstract contract SlasherBase is SlasherStorage { ) internal view virtual { require(account == slasher, OnlySlasher()); } + + /// @notice Internal function to update stake weights for the given operator + /// @param operator The operator to update + function _updateOperatorStakeWeights( + address operator + ) internal virtual { + address[] memory operators = new address[](1); + operators[0] = operator; + slashingRegistryCoordinator.updateOperators(operators); + } } diff --git a/src/slashers/base/SlasherStorage.sol b/src/slashers/base/SlasherStorage.sol index 993d49fb9..afdf1dbfc 100644 --- a/src/slashers/base/SlasherStorage.sol +++ b/src/slashers/base/SlasherStorage.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.27; import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {ISlashingRegistryCoordinator} from "../../interfaces/ISlashingRegistryCoordinator.sol"; import {ISlasher} from "../../interfaces/ISlasher.sol"; @@ -16,21 +17,27 @@ abstract contract SlasherStorage is ISlasher { * */ - /// @notice the AllocationManager that tracks OperatorSets and Slashing in EigenLayer + /// @notice The `AllocationManager` tracks operator sets, operator set allocations, and slashing in EigenLayer. IAllocationManager public immutable allocationManager; - /// @notice the SlashingRegistryCoordinator for this AVS + /// @notice The `StrategyManager` handles strategy inflows/outflows. + IStrategyManager public immutable strategyManager; + /// @notice The `SlashingRegistryCoordinator` for this AVS. ISlashingRegistryCoordinator public immutable slashingRegistryCoordinator; + /// @notice the address of the slasher address public immutable slasher; - uint256 public nextRequestId; + /// @dev DEPRECATED -- `AllocationManager` now tracks monotonically increasing `slashId`. + uint256 private __deprecated_nextRequestId; constructor( IAllocationManager _allocationManager, + IStrategyManager _strategyManager, ISlashingRegistryCoordinator _slashingRegistryCoordinator, address _slasher ) { allocationManager = _allocationManager; + strategyManager = _strategyManager; slashingRegistryCoordinator = _slashingRegistryCoordinator; slasher = _slasher; } diff --git a/test/integration/IntegrationDeployer.t.sol b/test/integration/IntegrationDeployer.t.sol index 1d9dcc9ee..934bb7256 100644 --- a/test/integration/IntegrationDeployer.t.sol +++ b/test/integration/IntegrationDeployer.t.sol @@ -22,6 +22,7 @@ import "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; import "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; +import "eigenlayer-contracts/src/contracts/strategies/EigenStrategy.sol"; import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; import "eigenlayer-contracts/src/contracts/permissions/PermissionController.sol"; import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol"; @@ -206,7 +207,7 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { "v0.0.1" ); StrategyManager strategyManagerImplementation = - new StrategyManager(delegationManager, pauserRegistry, "v0.0.1"); + new StrategyManager(allocationManager, delegationManager, pauserRegistry, "v0.0.1"); EigenPodManager eigenPodManagerImplementation = new EigenPodManager( ethPOSDeposit, eigenPodBeacon, delegationManager, pauserRegistry, "v0.0.1" ); @@ -229,8 +230,12 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { }) ); + IStrategy eigenStrategy = + IStrategy(new EigenStrategy(strategyManager, pauserRegistry, "v0.0.1")); + AllocationManager allocationManagerImplementation = new AllocationManager( delegationManager, + eigenStrategy, pauserRegistry, permissionController, uint32(7 days), // DEALLOCATION_DELAY diff --git a/test/mocks/AllocationManagerMock.sol b/test/mocks/AllocationManagerMock.sol index 98bcd3724..0ac14f520 100644 --- a/test/mocks/AllocationManagerMock.sol +++ b/test/mocks/AllocationManagerMock.sol @@ -11,9 +11,14 @@ import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPa import {ISemVerMixin} from "eigenlayer-contracts/src/contracts/interfaces/ISemVerMixin.sol"; contract AllocationManagerIntermediate is IAllocationManager { - function initialize(address initialOwner, uint256 initialPausedStatus) external virtual {} + function initialize( + uint256 initialPausedStatus + ) external virtual {} - function slashOperator(address avs, SlashingParams calldata params) external virtual {} + function slashOperator( + address avs, + SlashingParams calldata params + ) external virtual returns (uint256, uint256[] memory) {} function modifyAllocations( address operator, @@ -43,6 +48,12 @@ contract AllocationManagerIntermediate is IAllocationManager { function createOperatorSets(address avs, CreateSetParams[] calldata params) external virtual {} + function createRedistributingOperatorSets( + address avs, + CreateSetParams[] calldata params, + address[] calldata redistributionRecipients + ) external virtual {} + function addStrategiesToOperatorSet( address avs, uint32 operatorSetId, @@ -183,6 +194,22 @@ contract AllocationManagerIntermediate is IAllocationManager { function version() external pure virtual returns (string memory) { return "v0.0.1"; } + + function getRedistributionRecipient( + OperatorSet memory operatorSet + ) external view virtual returns (address) {} + + function isRedistributingOperatorSet( + OperatorSet memory operatorSet + ) external view virtual returns (bool) {} + + function getSlashCount( + OperatorSet memory operatorSet + ) external view virtual returns (uint256) {} + + function isOperatorRedistributable( + address operator + ) external view virtual returns (bool) {} } contract AllocationManagerMock is AllocationManagerIntermediate { diff --git a/test/mocks/DelegationMock.sol b/test/mocks/DelegationMock.sol index 6e0c351ea..58b55b8d7 100644 --- a/test/mocks/DelegationMock.sol +++ b/test/mocks/DelegationMock.sol @@ -4,10 +4,11 @@ pragma solidity ^0.8.27; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {console2 as console} from "forge-std/Test.sol"; -import {IDelegationManager} from - "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import {IDelegationManagerTypes} from - "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import { + OperatorSet, + IDelegationManager, + IDelegationManagerTypes +} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; @@ -20,7 +21,9 @@ import {ISemVerMixin} from "eigenlayer-contracts/src/contracts/interfaces/ISemVe import {SlashingLib} from "eigenlayer-contracts/src/contracts/libraries/SlashingLib.sol"; contract DelegationIntermediate is IDelegationManager { - function initialize(address initialOwner, uint256 initialPausedStatus) external virtual {} + function initialize( + uint256 initialPausedStatus + ) external virtual {} function registerAsOperator( OperatorDetails calldata registeringOperatorDetails, @@ -288,6 +291,15 @@ contract DelegationIntermediate is IDelegationManager { uint256[] memory withdrawableShares ) external view override returns (uint256[] memory) {} + function slashOperatorShares( + address operator, + OperatorSet calldata operatorSet, + uint256 slashId, + IStrategy strategy, + uint64 prevMaxMagnitude, + uint64 newMaxMagnitude + ) external virtual returns (uint256 totalDepositSharesToSlash) {} + /** * @notice Returns the domain separator used for EIP-712 signatures * @return The domain separator diff --git a/test/mocks/EigenPodManagerMock.sol b/test/mocks/EigenPodManagerMock.sol index 121a5435e..ce6e7bf82 100644 --- a/test/mocks/EigenPodManagerMock.sol +++ b/test/mocks/EigenPodManagerMock.sol @@ -126,6 +126,13 @@ contract EigenPodManagerMock is Test, Pausable, IEigenPodManager { function increaseBurnableShares(IStrategy strategy, uint256 addedSharesToBurn) external {} + function increaseBurnOrRedistributableShares( + OperatorSet calldata, + uint256, + IStrategy, + uint256 addedSharesToBurn + ) external {} + /** * @notice Returns the version of the contract * @return The version string diff --git a/test/unit/InstantSlasher.t.sol b/test/unit/InstantSlasher.t.sol index 4f33b39ab..95436ccfb 100644 --- a/test/unit/InstantSlasher.t.sol +++ b/test/unit/InstantSlasher.t.sol @@ -101,14 +101,12 @@ contract InstantSlasherTest is Test { configData.strategyManager.initialStrategyWhitelister = proxyAdminOwner; configData.strategyManager.initPausedStatus = 0; - configData.delegationManager.initialOwner = proxyAdminOwner; configData.delegationManager.minWithdrawalDelayBlocks = 50400; configData.delegationManager.initPausedStatus = 0; configData.eigenPodManager.initialOwner = proxyAdminOwner; configData.eigenPodManager.initPausedStatus = 0; - configData.allocationManager.initialOwner = proxyAdminOwner; configData.allocationManager.deallocationDelay = DEALLOCATION_DELAY; configData.allocationManager.allocationConfigurationDelay = ALLOCATION_CONFIGURATION_DELAY; configData.allocationManager.initPausedStatus = 0; @@ -184,6 +182,7 @@ contract InstantSlasherTest is Test { .deployMiddleware( address(proxyAdmin), coreDeployment.allocationManager, + coreDeployment.strategyManager, address(pauserRegistry), middlewareConfig ); diff --git a/test/unit/SlashingRegistryCoordinatorUnit.t.sol b/test/unit/SlashingRegistryCoordinatorUnit.t.sol index a7231a98e..cfbc0ad73 100644 --- a/test/unit/SlashingRegistryCoordinatorUnit.t.sol +++ b/test/unit/SlashingRegistryCoordinatorUnit.t.sol @@ -181,14 +181,12 @@ contract SlashingRegistryCoordinatorUnitTestSetup is configData.strategyManager.initialStrategyWhitelister = proxyAdminOwner; configData.strategyManager.initPausedStatus = 0; - configData.delegationManager.initialOwner = proxyAdminOwner; configData.delegationManager.minWithdrawalDelayBlocks = 100800; configData.delegationManager.initPausedStatus = 0; configData.eigenPodManager.initialOwner = proxyAdminOwner; configData.eigenPodManager.initPausedStatus = 0; - configData.allocationManager.initialOwner = proxyAdminOwner; configData.allocationManager.deallocationDelay = DEALLOCATION_DELAY; configData.allocationManager.allocationConfigurationDelay = ALLOCATION_CONFIGURATION_DELAY; configData.allocationManager.initPausedStatus = 0; @@ -254,6 +252,7 @@ contract SlashingRegistryCoordinatorUnitTestSetup is .deployMiddleware( address(proxyAdmin), coreDeployment.allocationManager, + coreDeployment.strategyManager, address(pauserRegistry), middlewareConfig ); diff --git a/test/unit/VetoableSlasher.t.sol b/test/unit/VetoableSlasher.t.sol index d009c17ce..889ab796f 100644 --- a/test/unit/VetoableSlasher.t.sol +++ b/test/unit/VetoableSlasher.t.sol @@ -108,14 +108,12 @@ contract VetoableSlasherTest is Test { configData.strategyManager.initialStrategyWhitelister = proxyAdminOwner; configData.strategyManager.initPausedStatus = 0; - configData.delegationManager.initialOwner = proxyAdminOwner; configData.delegationManager.minWithdrawalDelayBlocks = 50400; configData.delegationManager.initPausedStatus = 0; configData.eigenPodManager.initialOwner = proxyAdminOwner; configData.eigenPodManager.initPausedStatus = 0; - configData.allocationManager.initialOwner = proxyAdminOwner; configData.allocationManager.deallocationDelay = DEALLOCATION_DELAY; configData.allocationManager.allocationConfigurationDelay = ALLOCATION_CONFIGURATION_DELAY; configData.allocationManager.initPausedStatus = 0; @@ -188,6 +186,7 @@ contract VetoableSlasherTest is Test { .deployMiddleware( address(proxyAdmin), coreDeployment.allocationManager, + coreDeployment.strategyManager, address(pauserRegistry), middlewareConfig ); @@ -203,6 +202,7 @@ contract VetoableSlasherTest is Test { vetoableSlasherImplementation = new VetoableSlasher( IAllocationManager(coreDeployment.allocationManager), + IStrategyManager(coreDeployment.strategyManager), ISlashingRegistryCoordinator(slashingRegistryCoordinator), slasher, vetoCommittee, diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index dff9a02b3..79bf95094 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -58,7 +58,6 @@ library CoreDeployLib { struct DelegationManagerConfig { uint256 initPausedStatus; - address initialOwner; uint32 minWithdrawalDelayBlocks; } @@ -69,7 +68,6 @@ library CoreDeployLib { struct AllocationManagerConfig { uint256 initPausedStatus; - address initialOwner; uint32 deallocationDelay; uint32 allocationConfigurationDelay; } @@ -129,6 +127,7 @@ library CoreDeployLib { address strategyBeacon; address rewardsCoordinator; address permissionController; + address eigenStrategy; // TODO: initialize } function deployContracts( @@ -170,6 +169,7 @@ library CoreDeployLib { address strategyManagerImpl = address( new StrategyManager( + IAllocationManager(deployments.allocationManager), IDelegationManager(deployments.delegationManager), IPauserRegistry(deployments.pauserRegistry), "1.0.0" @@ -179,6 +179,7 @@ library CoreDeployLib { address allocationManagerImpl = address( new AllocationManager( IDelegationManager(deployments.delegationManager), + IStrategy(deployments.eigenStrategy), IPauserRegistry(deployments.pauserRegistry), IPermissionController(deployments.permissionController), config.allocationManager.deallocationDelay, @@ -223,16 +224,14 @@ library CoreDeployLib { ); upgradeCall = abi.encodeCall( - DelegationManager.initialize, - (config.delegationManager.initialOwner, config.delegationManager.initPausedStatus) + DelegationManager.initialize, (config.delegationManager.initPausedStatus) ); UpgradeableProxyLib.upgradeAndCall( deployments.delegationManager, delegationManagerImpl, upgradeCall ); upgradeCall = abi.encodeCall( - AllocationManager.initialize, - (config.allocationManager.initialOwner, config.allocationManager.initPausedStatus) + AllocationManager.initialize, (config.allocationManager.initPausedStatus) ); UpgradeableProxyLib.upgradeAndCall( deployments.allocationManager, allocationManagerImpl, upgradeCall diff --git a/test/utils/MiddlewareDeployLib.sol b/test/utils/MiddlewareDeployLib.sol index 2630fb802..47848184f 100644 --- a/test/utils/MiddlewareDeployLib.sol +++ b/test/utils/MiddlewareDeployLib.sol @@ -7,6 +7,7 @@ import {TransparentUpgradeableProxy} from import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; @@ -109,6 +110,7 @@ library MiddlewareDeployLib { function deployMiddleware( address proxyAdmin, address allocationManager, + address strategyManager, address pauserRegistry, MiddlewareDeployConfig memory config ) internal returns (MiddlewareDeployData memory result) { @@ -118,7 +120,7 @@ library MiddlewareDeployLib { upgradeCoordinator( result, allocationManager, pauserRegistry, config.slashingRegistryCoordinator ); - upgradeInstantSlasher(result, allocationManager, config.instantSlasher); + upgradeInstantSlasher(result, allocationManager, strategyManager, config.instantSlasher); return result; } @@ -319,11 +321,13 @@ library MiddlewareDeployLib { function upgradeInstantSlasher( MiddlewareDeployData memory deployments, address allocationManager, + address strategyManager, InstantSlasherConfig memory slasherConfig ) internal { address instantSlasherImpl = address( new InstantSlasher( IAllocationManager(allocationManager), + IStrategyManager(strategyManager), ISlashingRegistryCoordinator(deployments.slashingRegistryCoordinator), slasherConfig.slasher ) diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index ad1547c65..d786de1d1 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -6,6 +6,8 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {EigenStrategy} from "eigenlayer-contracts/src/contracts/strategies/EigenStrategy.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import { @@ -273,8 +275,15 @@ contract MockAVSDeployer is Test { address(serviceManagerImplementation) ); + IStrategy eigenStrategy = IStrategy( + new EigenStrategy( + IStrategyManager(address(strategyManagerMock)), pauserRegistry, "v0.0.1" + ) + ); + allocationManagerImplementation = new AllocationManager( delegationMock, + eigenStrategy, pauserRegistry, permissionControllerMock, uint32(7 days), // DEALLOCATION_DELAY