diff --git a/.github/workflows/forge-test-intense.yml b/.github/workflows/forge-test-intense.yml index 5f17cf63..1091e5be 100644 --- a/.github/workflows/forge-test-intense.yml +++ b/.github/workflows/forge-test-intense.yml @@ -29,7 +29,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: stable + version: v1.3.5 # Build the project and display contract sizes. - name: Forge Build diff --git a/.github/workflows/foundry.yml b/.github/workflows/foundry.yml index 0ea35815..a82ffd35 100644 --- a/.github/workflows/foundry.yml +++ b/.github/workflows/foundry.yml @@ -33,7 +33,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: stable + version: v1.3.5 # Run Forge's formatting checker to ensure consistent code style. - name: Forge Fmt @@ -73,7 +73,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: stable + version: v1.3.5 # Install LCOV for coverage report generation. - name: Install LCOV diff --git a/.github/workflows/storage-report.yml b/.github/workflows/storage-report.yml index ddd22a2e..fa196822 100644 --- a/.github/workflows/storage-report.yml +++ b/.github/workflows/storage-report.yml @@ -22,7 +22,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: v1.3.5 - name: "Generate and prepare the storage reports for current branch" run: | diff --git a/foundry.lock b/foundry.lock index e503ae3c..31cfd869 100644 --- a/foundry.lock +++ b/foundry.lock @@ -1,6 +1,6 @@ { "lib/eigenlayer-contracts": { - "rev": "31aade2fc3bf6e2c0160cc2e7c7be1a6017296e5" + "rev": "b9c1a6118534d19dafec502849e557ea68dff494" }, "lib/forge-std": { "rev": "77041d2ce690e692d6e03cc812b57d1ddaa4d505" diff --git a/foundry.toml b/foundry.toml index 9d48c79e..7751ee1c 100644 --- a/foundry.toml +++ b/foundry.toml @@ -24,7 +24,7 @@ ] # Specifies the exact version of Solidity to use, overriding auto-detection. - solc_version = '0.8.27' + solc_version = '0.8.29' # If enabled, treats Solidity compiler warnings as errors, preventing artifact generation if warnings are present. deny_warnings = false # If set to true, changes compilation pipeline to go through the new IR optimizer. diff --git a/lib/eigenlayer-contracts b/lib/eigenlayer-contracts index 31aade2f..b9c1a611 160000 --- a/lib/eigenlayer-contracts +++ b/lib/eigenlayer-contracts @@ -1 +1 @@ -Subproject commit 31aade2fc3bf6e2c0160cc2e7c7be1a6017296e5 +Subproject commit b9c1a6118534d19dafec502849e557ea68dff494 diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 2bf5a5f4..bc803336 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -289,13 +289,7 @@ contract RegistryCoordinator is SlashingRegistryCoordinator, RegistryCoordinator * @notice Returns the version of the contract * @return The version string */ - function version() - public - view - virtual - override(ISemVerMixin, SemVerMixin) - returns (string memory) - { + function version() public view virtual override(SemVerMixin) returns (string memory) { return "v0.0.1"; } } diff --git a/src/SlashingRegistryCoordinator.sol b/src/SlashingRegistryCoordinator.sol index 1b4ad47f..01c334ab 100644 --- a/src/SlashingRegistryCoordinator.sol +++ b/src/SlashingRegistryCoordinator.sol @@ -125,7 +125,8 @@ contract SlashingRegistryCoordinator is minimumStake, strategyParams, IStakeRegistryTypes.StakeType.TOTAL_DELEGATED, - 0 + 0, + DELEGATED_STAKE_SLASHER ); } @@ -134,14 +135,16 @@ contract SlashingRegistryCoordinator is OperatorSetParam memory operatorSetParams, uint96 minimumStake, IStakeRegistryTypes.StrategyParams[] memory strategyParams, - uint32 lookAheadPeriod + uint32 lookAheadPeriod, + address slasher ) external virtual onlyOwner { _createQuorum( operatorSetParams, minimumStake, strategyParams, IStakeRegistryTypes.StakeType.TOTAL_SLASHABLE, - lookAheadPeriod + lookAheadPeriod, + slasher ); } @@ -780,13 +783,15 @@ contract SlashingRegistryCoordinator is * registered * @param strategyParams a list of strategies and multipliers used by the StakeRegistry to * calculate an operator's stake weight for the quorum + * @param slasher the address of the slasher to use for the quorum (operatorSet) */ function _createQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, IStakeRegistryTypes.StrategyParams[] memory strategyParams, IStakeRegistryTypes.StakeType stakeType, - uint32 lookAheadPeriod + uint32 lookAheadPeriod, + address slasher ) internal { // The previous quorum count is the new quorum's number, // this is because quorum numbers begin from index 0. @@ -803,8 +808,8 @@ contract SlashingRegistryCoordinator is _setOperatorSetParams(quorumNumber, operatorSetParams); // Create array of CreateSetParams for the new quorum - IAllocationManagerTypes.CreateSetParams[] memory createSetParams = - new IAllocationManagerTypes.CreateSetParams[](1); + IAllocationManagerTypes.CreateSetParamsV2[] memory createSetParams = + new IAllocationManagerTypes.CreateSetParamsV2[](1); // Extract strategies from strategyParams IStrategy[] memory strategies = new IStrategy[](strategyParams.length); @@ -813,9 +818,10 @@ contract SlashingRegistryCoordinator is } // Initialize CreateSetParams with quorumNumber as operatorSetId - createSetParams[0] = IAllocationManagerTypes.CreateSetParams({ + createSetParams[0] = IAllocationManagerTypes.CreateSetParamsV2({ operatorSetId: quorumNumber, - strategies: strategies + strategies: strategies, + slasher: slasher }); allocationManager.createOperatorSets({avs: avs, params: createSetParams}); diff --git a/src/SlashingRegistryCoordinatorStorage.sol b/src/SlashingRegistryCoordinatorStorage.sol index f843aa18..6a9042af 100644 --- a/src/SlashingRegistryCoordinatorStorage.sol +++ b/src/SlashingRegistryCoordinatorStorage.sol @@ -45,6 +45,10 @@ abstract contract SlashingRegistryCoordinatorStorage is ISlashingRegistryCoordin /// @notice the Index Registry contract that will keep track of operators' indexes IIndexRegistry public immutable indexRegistry; + /// @notice For delegated stake quorums, the address that is set to slash + /// @dev This address is set to the burn address as 0 addresses are not valid slasher addresses + address public constant DELEGATED_STAKE_SLASHER = 0x00000000000000000000000000000000000E16E4; + /// EigenLayer contracts /// @notice the AllocationManager that tracks OperatorSets and Slashing in EigenLayer IAllocationManager public immutable allocationManager; diff --git a/src/interfaces/ISlashingRegistryCoordinator.sol b/src/interfaces/ISlashingRegistryCoordinator.sol index 6ffd1de9..08e90a60 100644 --- a/src/interfaces/ISlashingRegistryCoordinator.sol +++ b/src/interfaces/ISlashingRegistryCoordinator.sol @@ -407,13 +407,16 @@ interface ISlashingRegistryCoordinator is * @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. + * @param slasher The address of the slasher to use for the operatorSet (quorum) in EigenLayer core * @dev Can only be called when operator sets are enabled. + * @dev The lookahead period is set to 0 and slasher is set to DELEGATED_STAKE_SLASHER for total delegated stake quorums */ function createSlashableStakeQuorum( OperatorSetParam memory operatorSetParams, uint96 minimumStake, IStakeRegistryTypes.StrategyParams[] memory strategyParams, - uint32 lookAheadPeriod + uint32 lookAheadPeriod, + address slasher ) external; /** diff --git a/test/fork/EigenDA.t.sol b/test/fork/EigenDA.t.sol index 419c1492..196d6064 100644 --- a/test/fork/EigenDA.t.sol +++ b/test/fork/EigenDA.t.sol @@ -19,8 +19,6 @@ import {IIndexRegistry} from "../../src/interfaces/IIndexRegistry.sol"; import {ISlashingRegistryCoordinator} from "../../src/interfaces/ISlashingRegistryCoordinator.sol"; import {ISocketRegistry} from "../../src/interfaces/ISocketRegistry.sol"; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; -import {IAllocationManager} from - "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; @@ -35,6 +33,7 @@ import { OperatorSet, IAllocationManagerTypes } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { ISignatureUtilsMixin, @@ -220,6 +219,7 @@ contract EigenDATest is Test { IStrategyManager public strategyManager; function setUp() public virtual { + vm.skip(true); // TODO: change fork to using Hoodi once DA migrates // Setup the Holesky fork and load EigenDA deployment data eigenDAData = _setupEigenDAFork("test/utils"); @@ -687,7 +687,7 @@ contract EigenDATest is Test { vm.startPrank(serviceManagerOwner); registryCoordinator.createSlashableStakeQuorum( - operatorSetParam, minimumStake, strategyParams, lookAheadPeriod + operatorSetParam, minimumStake, strategyParams, lookAheadPeriod, serviceManagerOwner ); vm.stopPrank(); } @@ -787,16 +787,16 @@ contract EigenDATest is Test { serviceManager.setAppointee( address(registryCoordinator), allocationManagerAddr, - IAllocationManager.createOperatorSets.selector + bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) ); serviceManager.setAppointee( serviceManagerOwner, allocationManagerAddr, - IAllocationManager.updateAVSMetadataURI.selector + AllocationManager.updateAVSMetadataURI.selector ); serviceManager.setAppointee( - serviceManagerOwner, allocationManagerAddr, IAllocationManager.setAVSRegistrar.selector + serviceManagerOwner, allocationManagerAddr, AllocationManager.setAVSRegistrar.selector ); console.log("Appointees set for required permissions"); diff --git a/test/fork/End2End.t.sol b/test/fork/End2End.t.sol index dd9fce35..a985e089 100644 --- a/test/fork/End2End.t.sol +++ b/test/fork/End2End.t.sol @@ -105,6 +105,7 @@ contract End2EndForkTest is Test { } function testEndToEndSetup_M2Migration() public { + vm.skip(true); // TODO: change fork to using Hoodi once DA migrates ( OperatorLib.Operator[] memory operators, DeploymentData memory coreDeployment, @@ -204,7 +205,7 @@ contract End2EndForkTest is Test { address(middlewareDeployment.serviceManager), address(middlewareDeployment.registryCoordinator), coreDeployment.allocationManager, - AllocationManager.createOperatorSets.selector + bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) ); vm.stopPrank(); } @@ -365,7 +366,7 @@ contract End2EndForkTest is Test { }); RegistryCoordinator(middlewareDeployment.registryCoordinator).createSlashableStakeQuorum( - operatorSetParams, 100, strategyParams, 10 + operatorSetParams, 100, strategyParams, 10, address(middlewareDeployment.serviceManager) ); vm.stopPrank(); diff --git a/test/integration/IntegrationConfig.t.sol b/test/integration/IntegrationConfig.t.sol index f1ff0a89..b0a9376e 100644 --- a/test/integration/IntegrationConfig.t.sol +++ b/test/integration/IntegrationConfig.t.sol @@ -204,7 +204,8 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { operatorSetParams: operatorSet, minimumStake: minimumStake, strategyParams: strategyParams, - lookAheadPeriod: 0 + lookAheadPeriod: 0, + slasher: registryCoordinatorOwner }); } else if (quorumType == BOTH) { // randomly choose one of the two @@ -222,7 +223,8 @@ contract IntegrationConfig is IntegrationDeployer, G2Operations, Constants { operatorSetParams: operatorSet, minimumStake: minimumStake, strategyParams: strategyParams, - lookAheadPeriod: 0 + lookAheadPeriod: 0, + slasher: registryCoordinatorOwner }); } } diff --git a/test/integration/IntegrationDeployer.t.sol b/test/integration/IntegrationDeployer.t.sol index b695633a..018a0cce 100644 --- a/test/integration/IntegrationDeployer.t.sol +++ b/test/integration/IntegrationDeployer.t.sol @@ -18,6 +18,7 @@ import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; import "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; import "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; +import "eigenlayer-contracts/src/contracts/core/AllocationManagerView.sol"; import "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; import "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; @@ -190,11 +191,11 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { ); // Deploy EigenPod Contracts - pod = new EigenPod(ethPOSDeposit, eigenPodManager, "v0.0.1"); + pod = new EigenPod(ethPOSDeposit, eigenPodManager); eigenPodBeacon = new UpgradeableBeacon(address(pod)); - PermissionController permissionControllerImplementation = new PermissionController("v0.0.1"); + PermissionController permissionControllerImplementation = new PermissionController(); // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs DelegationManager delegationImplementation = new DelegationManager( @@ -208,9 +209,8 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { ); StrategyManager strategyManagerImplementation = new StrategyManager(allocationManager, delegationManager, pauserRegistry, "v0.0.1"); - EigenPodManager eigenPodManagerImplementation = new EigenPodManager( - ethPOSDeposit, eigenPodBeacon, delegationManager, pauserRegistry, "v0.0.1" - ); + EigenPodManager eigenPodManagerImplementation = + new EigenPodManager(ethPOSDeposit, eigenPodBeacon, delegationManager, pauserRegistry); AVSDirectory avsDirectoryImplementation = new AVSDirectory(delegationManager, pauserRegistry, "v0.0.1"); @@ -225,22 +225,24 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { MAX_REWARDS_DURATION: MAX_REWARDS_DURATION, MAX_RETROACTIVE_LENGTH: MAX_RETROACTIVE_LENGTH, MAX_FUTURE_LENGTH: MAX_FUTURE_LENGTH, - GENESIS_REWARDS_TIMESTAMP: GENESIS_REWARDS_TIMESTAMP, - version: "v0.0.1" + GENESIS_REWARDS_TIMESTAMP: GENESIS_REWARDS_TIMESTAMP }) ); - IStrategy eigenStrategy = - IStrategy(new EigenStrategy(strategyManager, pauserRegistry, "v0.0.1")); + IStrategy eigenStrategy = IStrategy(new EigenStrategy(strategyManager, pauserRegistry)); + + AllocationManagerView allocationManagerView = new AllocationManagerView( + delegationManager, eigenStrategy, uint32(7 days), uint32(1 days) + ); AllocationManager allocationManagerImplementation = new AllocationManager( + allocationManagerView, delegationManager, eigenStrategy, pauserRegistry, permissionController, uint32(7 days), // DEALLOCATION_DELAY - uint32(1 days), // ALLOCATION_CONFIGURATION_DELAY - "v0.0.1" // Added config parameter + uint32(1 days) // ALLOCATION_CONFIGURATION_DELAY ); // Third, upgrade the proxy contracts to point to the implementations @@ -316,7 +318,7 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { ); // Deploy and whitelist strategies - baseStrategyImplementation = new StrategyBase(strategyManager, pauserRegistry, "v0.0.1"); + baseStrategyImplementation = new StrategyBase(strategyManager, pauserRegistry); for (uint256 i = 0; i < MAX_STRATEGY_COUNT; i++) { string memory number = uint256(i).toString(); string memory stratName = string.concat("StrategyToken", number); @@ -486,38 +488,38 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { serviceManager.setAppointee({ appointee: serviceManager.owner(), target: address(allocationManager), - selector: IAllocationManager.setAVSRegistrar.selector + selector: AllocationManager.setAVSRegistrar.selector }); // 2. set AVS metadata serviceManager.setAppointee({ appointee: serviceManager.owner(), target: address(allocationManager), - selector: IAllocationManager.updateAVSMetadataURI.selector + selector: AllocationManager.updateAVSMetadataURI.selector }); // 3. create operator sets serviceManager.setAppointee({ appointee: address(registryCoordinator), target: address(allocationManager), - selector: IAllocationManager.createOperatorSets.selector + selector: bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) }); // 4. deregister operator from operator sets serviceManager.setAppointee({ appointee: address(registryCoordinator), target: address(allocationManager), - selector: IAllocationManager.deregisterFromOperatorSets.selector + selector: AllocationManager.deregisterFromOperatorSets.selector }); // 5. add strategies to operator sets serviceManager.setAppointee({ appointee: address(registryCoordinator), target: address(stakeRegistry), - selector: IAllocationManager.addStrategiesToOperatorSet.selector + selector: AllocationManager.addStrategiesToOperatorSet.selector }); // 6. remove strategies from operator sets serviceManager.setAppointee({ appointee: address(registryCoordinator), target: address(stakeRegistry), - selector: IAllocationManager.removeStrategiesFromOperatorSet.selector + selector: AllocationManager.removeStrategiesFromOperatorSet.selector }); cheats.stopPrank(); _setOperatorSetsEnabled(false); @@ -530,31 +532,31 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { account: avsAccountIdentifier, appointee: address(avsAccountIdentifier), target: address(allocationManager), - selector: IAllocationManager.setAVSRegistrar.selector + selector: AllocationManager.setAVSRegistrar.selector }); permissionController.setAppointee({ account: avsAccountIdentifier, appointee: address(slashingRegistryCoordinator), target: address(allocationManager), - selector: IAllocationManager.createOperatorSets.selector + selector: bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) }); permissionController.setAppointee({ account: avsAccountIdentifier, appointee: address(slashingRegistryCoordinator), target: address(allocationManager), - selector: IAllocationManager.deregisterFromOperatorSets.selector + selector: AllocationManager.deregisterFromOperatorSets.selector }); permissionController.setAppointee({ account: avsAccountIdentifier, appointee: address(stakeRegistry), target: address(allocationManager), - selector: IAllocationManager.addStrategiesToOperatorSet.selector + selector: AllocationManager.addStrategiesToOperatorSet.selector }); permissionController.setAppointee({ account: avsAccountIdentifier, appointee: address(stakeRegistry), target: address(allocationManager), - selector: IAllocationManager.removeStrategiesFromOperatorSet.selector + selector: AllocationManager.removeStrategiesFromOperatorSet.selector }); // set AVS Registrar to slashingRegistryCoordinator allocationManager.setAVSRegistrar( diff --git a/test/mocks/AllocationManagerMock.sol b/test/mocks/AllocationManagerMock.sol index 4844bfb9..51808edc 100644 --- a/test/mocks/AllocationManagerMock.sol +++ b/test/mocks/AllocationManagerMock.sol @@ -9,6 +9,8 @@ import {IAVSRegistrar} from "eigenlayer-contracts/src/contracts/interfaces/IAVSR import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {ISemVerMixin} from "eigenlayer-contracts/src/contracts/interfaces/ISemVerMixin.sol"; +import {IDelegationManager} from + "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; contract AllocationManagerIntermediate is IAllocationManager { mapping(address avs => address avsRegistrar) internal _avsRegistrar; @@ -58,12 +60,23 @@ contract AllocationManagerIntermediate is IAllocationManager { function createOperatorSets(address avs, CreateSetParams[] calldata params) external virtual {} + function createOperatorSets( + address avs, + CreateSetParamsV2[] calldata params + ) external virtual {} + function createRedistributingOperatorSets( address avs, CreateSetParams[] calldata params, address[] calldata redistributionRecipients ) external virtual {} + function createRedistributingOperatorSets( + address avs, + CreateSetParamsV2[] calldata params, + address[] calldata redistributionRecipients + ) external virtual {} + function addStrategiesToOperatorSet( address avs, uint32 operatorSetId, @@ -218,6 +231,45 @@ contract AllocationManagerIntermediate is IAllocationManager { function isRedistributingOperatorSet( OperatorSet memory operatorSet ) external pure virtual returns (bool) {} + + function ALLOCATION_CONFIGURATION_DELAY() external pure virtual returns (uint32) {} + + function delegation() external pure virtual returns (IDelegationManager) {} + + function eigenStrategy() external pure virtual returns (IStrategy) {} + + function getPendingSlasher( + OperatorSet memory operatorSet + ) external view virtual returns (address pendingSlasher, uint32 effectBlock) {} + + function migrateSlashers( + OperatorSet[] memory operatorSets + ) external virtual {} + + function updateSlasher(OperatorSet memory operatorSet, address slasher) external virtual {} + + function getSlasher( + OperatorSet memory operatorSet + ) external view virtual returns (address slasher) {} + + // Pause functions + function pause( + uint256 newPausedStatus + ) external virtual {} + + function unpause( + uint256 newPausedStatus + ) external virtual {} + + function paused() external view virtual returns (uint256) {} + + function paused( + uint8 index + ) external view virtual returns (bool) {} + + function pauseAll() external virtual {} + + function pauserRegistry() external view virtual returns (IPauserRegistry) {} } contract AllocationManagerMock is AllocationManagerIntermediate { diff --git a/test/mocks/KeyRegistrarMock.sol b/test/mocks/KeyRegistrarMock.sol index f6022868..f6d399f9 100644 --- a/test/mocks/KeyRegistrarMock.sol +++ b/test/mocks/KeyRegistrarMock.sol @@ -32,6 +32,29 @@ contract KeyRegistrarMock is IKeyRegistrar { function configureOperatorSet(OperatorSet memory operatorSet, CurveType curveType) external {} + function configureOperatorSetWithMinDelay( + OperatorSet memory operatorSet, + CurveType curveType, + uint64 minDelaySeconds + ) external {} + + function finalizeScheduledRotation( + address operator, + OperatorSet memory operatorSet + ) external returns (bool) {} + + function rotateKey( + address operator, + OperatorSet memory operatorSet, + bytes calldata pubkey, + bytes calldata signature + ) external {} + + function setMinKeyRotationDelay( + OperatorSet memory operatorSet, + uint64 minDelaySeconds + ) external {} + function registerKey( address operator, OperatorSet memory operatorSet, diff --git a/test/mocks/PermissionControllerMock.sol b/test/mocks/PermissionControllerMock.sol index 6a6cc05e..d6673184 100644 --- a/test/mocks/PermissionControllerMock.sol +++ b/test/mocks/PermissionControllerMock.sol @@ -50,7 +50,7 @@ contract PermissionControllerIntermediate is IPermissionController { address caller, address target, bytes4 selector - ) external virtual returns (bool) {} + ) external view virtual returns (bool) {} function getAppointeePermissions( address account, @@ -90,7 +90,7 @@ contract PermissionControllerMock is PermissionControllerIntermediate { address caller, address target, bytes4 selector - ) external override returns (bool) { + ) external view override returns (bool) { if (account == caller) return true; return _canCall[account][caller][target][selector]; } diff --git a/test/unit/InstantSlasher.t.sol b/test/unit/InstantSlasher.t.sol index 95436ccf..bc2e7714 100644 --- a/test/unit/InstantSlasher.t.sol +++ b/test/unit/InstantSlasher.t.sol @@ -189,12 +189,6 @@ contract InstantSlasherTest is Test { vm.stopPrank(); vm.startPrank(serviceManager); - PermissionController(coreDeployment.permissionController).setAppointee( - address(serviceManager), - address(instantSlasher), - coreDeployment.allocationManager, - AllocationManager.slashOperator.selector - ); slashingRegistryCoordinator = SlashingRegistryCoordinator(middlewareDeployments.slashingRegistryCoordinator); @@ -205,14 +199,7 @@ contract InstantSlasherTest is Test { address(serviceManager), address(slashingRegistryCoordinator), coreDeployment.allocationManager, - AllocationManager.createOperatorSets.selector - ); - - PermissionController(coreDeployment.permissionController).setAppointee( - address(serviceManager), - address(instantSlasher), - coreDeployment.allocationManager, - AllocationManager.slashOperator.selector + bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) ); PermissionController(coreDeployment.permissionController).setAppointee( @@ -255,7 +242,7 @@ contract InstantSlasherTest is Test { serviceManager, "fake-avs-metadata" ); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, 1 ether, strategyParams, 0 + operatorSetParams, 1 ether, strategyParams, 0, address(instantSlasher) ); vm.stopPrank(); @@ -276,6 +263,8 @@ contract InstantSlasherTest is Test { } function test_fulfillSlashingRequest() public { + // Roll block number so we don't underflow in the DM when calculating `prevQueuedScaledShares` + vm.roll(block.number + ALLOCATION_CONFIGURATION_DELAY + 1); vm.startPrank(operatorWallet.key.addr); IDelegationManager(coreDeployment.delegationManager).registerAsOperator( address(0), 1, "metadata" @@ -297,9 +286,7 @@ contract InstantSlasherTest is Test { (bool isSet,) = IAllocationManager(coreDeployment.allocationManager).getAllocationDelay( operatorWallet.key.addr ); - assertFalse(isSet, "Operator allocation delay not set"); - - vm.roll(block.number + ALLOCATION_CONFIGURATION_DELAY + 1); + assertTrue(isSet, "Operator allocation delay set"); IStrategy[] memory allocStrategies = new IStrategy[](1); allocStrategies[0] = mockStrategy; diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index 9334d27a..a911672b 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -2417,7 +2417,11 @@ contract RegistryCoordinatorUnitTests_BeforeMigration is RegistryCoordinatorUnit // Attempt to create quorum with slashable stake type before enabling operator sets cheats.prank(registryCoordinatorOwner); registryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, strategyParams, lookAheadPeriod + operatorSetParams, + minimumStake, + strategyParams, + lookAheadPeriod, + registryCoordinatorOwner ); assertEq(registryCoordinator.quorumCount(), 1, "New quorum 0 should be created"); assertFalse(registryCoordinator.isM2Quorum(0), "Quorum created should not be an M2 quorum"); @@ -2523,7 +2527,11 @@ contract RegistryCoordinatorUnitTests_AfterMigration is RegistryCoordinatorUnitT // Create slashable stake quorum cheats.prank(registryCoordinatorOwner); registryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, strategyParams, lookAheadPeriod + operatorSetParams, + minimumStake, + strategyParams, + lookAheadPeriod, + registryCoordinatorOwner ); } diff --git a/test/unit/ServiceManagerBase.t.sol b/test/unit/ServiceManagerBase.t.sol index df571117..492d2e57 100644 --- a/test/unit/ServiceManagerBase.t.sol +++ b/test/unit/ServiceManagerBase.t.sol @@ -18,7 +18,8 @@ import {IServiceManagerErrors} from "../../src/interfaces/IServiceManager.sol"; import { IAllocationManagerTypes, - IAllocationManager + IAllocationManager, + IAllocationManagerActions } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import "../utils/MockAVSDeployer.sol"; @@ -77,8 +78,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve MAX_REWARDS_DURATION: MAX_REWARDS_DURATION, MAX_RETROACTIVE_LENGTH: MAX_RETROACTIVE_LENGTH, MAX_FUTURE_LENGTH: MAX_FUTURE_LENGTH, - GENESIS_REWARDS_TIMESTAMP: GENESIS_REWARDS_TIMESTAMP, - version: "v0.0.1" + GENESIS_REWARDS_TIMESTAMP: GENESIS_REWARDS_TIMESTAMP }) ); @@ -168,9 +168,8 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve IERC20 token3 = new ERC20PresetFixedSupply( "pepe wif avs", "MOCK3", mockTokenInitialSupply, address(this) ); - strategyImplementation = new StrategyBase( - IStrategyManager(address(strategyManagerMock)), pauserRegistry, "v0.0.1" - ); + strategyImplementation = + new StrategyBase(IStrategyManager(address(strategyManagerMock)), pauserRegistry); strategyMock1 = StrategyBase( address( new TransparentUpgradeableProxy( @@ -935,7 +934,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve cheats.expectCall( address(allocationManagerMock), - abi.encodeCall(IAllocationManager.deregisterFromOperatorSets, (expectedParams)) + abi.encodeCall(AllocationManager.deregisterFromOperatorSets, (expectedParams)) ); // Call should only work from registryCoordinator diff --git a/test/unit/SlashingRegistryCoordinatorUnit.t.sol b/test/unit/SlashingRegistryCoordinatorUnit.t.sol index cfbc0ad7..2ef94c83 100644 --- a/test/unit/SlashingRegistryCoordinatorUnit.t.sol +++ b/test/unit/SlashingRegistryCoordinatorUnit.t.sol @@ -6,7 +6,8 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {InstantSlasher} from "../../src/slashers/InstantSlasher.sol"; import { IAllocationManager, - IAllocationManagerTypes + IAllocationManagerTypes, + IAllocationManagerActions } from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {OperatorSetLib} from "eigenlayer-contracts/src/contracts/libraries/OperatorSetLib.sol"; @@ -278,7 +279,7 @@ contract SlashingRegistryCoordinatorUnitTestSetup is address(serviceManager), address(slashingRegistryCoordinator), coreDeployment.allocationManager, - AllocationManager.createOperatorSets.selector + bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) ); PermissionController(coreDeployment.permissionController).setAppointee( @@ -669,7 +670,7 @@ contract SlashingRegistryCoordinator_CreateSlashableStakeQuorum is vm.prank(proxyAdminOwner); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod + operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod, proxyAdminOwner ); assertEq(slashingRegistryCoordinator.quorumCount(), initialQuorumCount + 1); @@ -691,7 +692,7 @@ contract SlashingRegistryCoordinator_CreateSlashableStakeQuorum is vm.prank(proxyAdminOwner); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, strategyParams, lookAheadPeriod + operatorSetParams, minimumStake, strategyParams, lookAheadPeriod, proxyAdminOwner ); assertEq(slashingRegistryCoordinator.quorumCount(), quorumNumber + 1); @@ -707,7 +708,7 @@ contract SlashingRegistryCoordinator_CreateSlashableStakeQuorum is vm.prank(address(0xdead)); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod + operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod, proxyAdminOwner ); } @@ -718,13 +719,17 @@ contract SlashingRegistryCoordinator_CreateSlashableStakeQuorum is // So we need to create 191 more for (uint8 i = 0; i < 191; i++) { slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod + operatorSetParams, + minimumStake, + getStrategyParams(), + lookAheadPeriod, + proxyAdminOwner ); } vm.expectRevert(MaxQuorumsReached.selector); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod + operatorSetParams, minimumStake, getStrategyParams(), lookAheadPeriod, proxyAdminOwner ); vm.stopPrank(); @@ -739,7 +744,11 @@ contract SlashingRegistryCoordinator_CreateSlashableStakeQuorum is vm.prank(proxyAdminOwner); vm.expectRevert(LookAheadPeriodTooLong.selector); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, minimumStake, getStrategyParams(), tooLongLookAheadPeriod + operatorSetParams, + minimumStake, + getStrategyParams(), + tooLongLookAheadPeriod, + proxyAdminOwner ); } } @@ -1345,7 +1354,7 @@ contract SlashingRegistryCoordinator_EjectOperator is SlashingRegistryCoordinato address(serviceManager), address(slashingRegistryCoordinator), address(coreDeployment.allocationManager), - IAllocationManager.deregisterFromOperatorSets.selector + AllocationManager.deregisterFromOperatorSets.selector ); registerOperatorInSlashingRegistryCoordinator(testOperator, "socket:8545", operatorSetIds); @@ -1586,7 +1595,7 @@ contract SlashingRegistryCoordinator_RegisterWithChurn is address(serviceManager), address(slashingRegistryCoordinator), address(coreDeployment.allocationManager), - IAllocationManager.deregisterFromOperatorSets.selector + AllocationManager.deregisterFromOperatorSets.selector ); } @@ -2058,7 +2067,7 @@ contract SlashingRegistryCoordinator_UpdateOperators is SlashingRegistryCoordina address(serviceManager), address(slashingRegistryCoordinator), address(coreDeployment.allocationManager), - IAllocationManager.deregisterFromOperatorSets.selector + AllocationManager.deregisterFromOperatorSets.selector ); } @@ -2269,7 +2278,7 @@ contract SlashingRegistryCoordinator_UpdateOperatorsForQuorum is address(serviceManager), address(slashingRegistryCoordinator), address(coreDeployment.allocationManager), - IAllocationManager.deregisterFromOperatorSets.selector + AllocationManager.deregisterFromOperatorSets.selector ); } diff --git a/test/unit/Utils.sol b/test/unit/Utils.sol index 89f274e8..463d8a3b 100644 --- a/test/unit/Utils.sol +++ b/test/unit/Utils.sol @@ -12,7 +12,7 @@ contract Utils { IPauserRegistry pauserRegistry, address admin ) public returns (StrategyBase) { - StrategyBase newStrategy = new StrategyBase(strategyManager, pauserRegistry, "v0.0.1"); + StrategyBase newStrategy = new StrategyBase(strategyManager, pauserRegistry); newStrategy = StrategyBase( address(new TransparentUpgradeableProxy(address(newStrategy), address(admin), "")) ); diff --git a/test/unit/VetoableSlasher.t.sol b/test/unit/VetoableSlasher.t.sol index 889ab796..c06616b3 100644 --- a/test/unit/VetoableSlasher.t.sol +++ b/test/unit/VetoableSlasher.t.sol @@ -223,18 +223,12 @@ contract VetoableSlasherTest is Test { vm.stopPrank(); vm.startPrank(serviceManager); - PermissionController(coreDeployment.permissionController).setAppointee( - address(serviceManager), - address(vetoableSlasher), - coreDeployment.allocationManager, - AllocationManager.slashOperator.selector - ); PermissionController(coreDeployment.permissionController).setAppointee( address(serviceManager), address(slashingRegistryCoordinator), coreDeployment.allocationManager, - AllocationManager.createOperatorSets.selector + bytes4(keccak256("createOperatorSets(address,(uint32,address[],address)[])")) ); PermissionController(coreDeployment.permissionController).setAppointee( @@ -277,7 +271,7 @@ contract VetoableSlasherTest is Test { serviceManager, "fake-avs-metadata" ); slashingRegistryCoordinator.createSlashableStakeQuorum( - operatorSetParams, 1 ether, strategyParams, 0 + operatorSetParams, 1 ether, strategyParams, 0, address(vetoableSlasher) ); vm.stopPrank(); diff --git a/test/unit/middlewareV2/AVSRegistrarAsIdentifierUnit.t.sol b/test/unit/middlewareV2/AVSRegistrarAsIdentifierUnit.t.sol index 879a1a3f..19e02cfd 100644 --- a/test/unit/middlewareV2/AVSRegistrarAsIdentifierUnit.t.sol +++ b/test/unit/middlewareV2/AVSRegistrarAsIdentifierUnit.t.sol @@ -13,6 +13,7 @@ import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; contract AVSRegistrarAsIdentifierUnitTests is AVSRegistrarBase { AVSRegistrarAsIdentifier public avsRegistrarAsIdentifier; @@ -86,7 +87,7 @@ contract AVSRegistrarAsIdentifierUnitTests_initialize is AVSRegistrarAsIdentifie vm.mockCall( address(allocationManagerMock), abi.encodeWithSelector( - IAllocationManager.updateAVSMetadataURI.selector, + AllocationManager.updateAVSMetadataURI.selector, address(avsRegistrarAsIdentifier), METADATA_URI ), @@ -95,7 +96,7 @@ contract AVSRegistrarAsIdentifierUnitTests_initialize is AVSRegistrarAsIdentifie vm.mockCall( address(allocationManagerMock), abi.encodeWithSelector( - IAllocationManager.setAVSRegistrar.selector, + AllocationManager.setAVSRegistrar.selector, address(avsRegistrarAsIdentifier), avsRegistrarAsIdentifier ), @@ -117,7 +118,7 @@ contract AVSRegistrarAsIdentifierUnitTests_initialize is AVSRegistrarAsIdentifie vm.expectCall( address(allocationManagerMock), abi.encodeWithSelector( - IAllocationManager.updateAVSMetadataURI.selector, + AllocationManager.updateAVSMetadataURI.selector, address(avsRegistrarAsIdentifier), METADATA_URI ) @@ -125,7 +126,7 @@ contract AVSRegistrarAsIdentifierUnitTests_initialize is AVSRegistrarAsIdentifie vm.expectCall( address(allocationManagerMock), abi.encodeWithSelector( - IAllocationManager.setAVSRegistrar.selector, + AllocationManager.setAVSRegistrar.selector, address(avsRegistrarAsIdentifier), avsRegistrarAsIdentifier ) @@ -147,12 +148,12 @@ contract AVSRegistrarAsIdentifierUnitTests_initialize is AVSRegistrarAsIdentifie // Initialize first vm.mockCall( address(allocationManagerMock), - abi.encodeWithSelector(IAllocationManager.updateAVSMetadataURI.selector), + abi.encodeWithSelector(AllocationManager.updateAVSMetadataURI.selector), "" ); vm.mockCall( address(allocationManagerMock), - abi.encodeWithSelector(IAllocationManager.setAVSRegistrar.selector), + abi.encodeWithSelector(AllocationManager.setAVSRegistrar.selector), "" ); vm.mockCall( diff --git a/test/unit/middlewareV2/MockDeployer.sol b/test/unit/middlewareV2/MockDeployer.sol index ba73cb71..8cb02176 100644 --- a/test/unit/middlewareV2/MockDeployer.sol +++ b/test/unit/middlewareV2/MockDeployer.sol @@ -60,7 +60,7 @@ abstract contract MockEigenLayerDeployer is Test { keyRegistrarMock = new KeyRegistrarMock(); // Deploy the actual PermissionController & KeyRegistrar implementations - permissionControllerImplementation = new PermissionController("9.9.9"); + permissionControllerImplementation = new PermissionController(); permissionController = PermissionController( address( new TransparentUpgradeableProxy( diff --git a/test/utils/CoreDeployLib.sol b/test/utils/CoreDeployLib.sol index 357e1a96..53ec6591 100644 --- a/test/utils/CoreDeployLib.sol +++ b/test/utils/CoreDeployLib.sol @@ -6,6 +6,8 @@ import {stdJson} from "forge-std/StdJson.sol"; import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {AllocationManagerView} from + "eigenlayer-contracts/src/contracts/core/AllocationManagerView.sol"; import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; import {DelegationManager} from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import {StrategyManager} from "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; @@ -27,6 +29,8 @@ import { import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol"; +import {IAllocationManagerView} from + "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IEigenPodManager} from "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; @@ -165,7 +169,7 @@ library CoreDeployLib { DeploymentConfigData memory config ) internal { // Deploy core implementations - address permissionControllerImpl = address(new PermissionController("1.0.0")); + address permissionControllerImpl = address(new PermissionController()); address strategyManagerImpl = address( new StrategyManager( @@ -176,15 +180,24 @@ library CoreDeployLib { ) ); + address allocationManagerView = address( + new AllocationManagerView( + IDelegationManager(deployments.delegationManager), + IStrategy(deployments.eigenStrategy), + config.allocationManager.deallocationDelay, + config.allocationManager.allocationConfigurationDelay + ) + ); + address allocationManagerImpl = address( new AllocationManager( + IAllocationManagerView(allocationManagerView), IDelegationManager(deployments.delegationManager), IStrategy(deployments.eigenStrategy), IPauserRegistry(deployments.pauserRegistry), IPermissionController(deployments.permissionController), config.allocationManager.deallocationDelay, - config.allocationManager.allocationConfigurationDelay, - "1.0.0" + config.allocationManager.allocationConfigurationDelay ) ); @@ -259,9 +272,7 @@ library CoreDeployLib { address eigenPodImpl = address( new EigenPod( - IETHPOSDeposit(ethPOSDeposit), - IEigenPodManager(deployments.eigenPodManager), - "1.0.0" + IETHPOSDeposit(ethPOSDeposit), IEigenPodManager(deployments.eigenPodManager) ) ); @@ -273,8 +284,7 @@ library CoreDeployLib { IETHPOSDeposit(ethPOSDeposit), IBeacon(deployments.eigenPodBeacon), IDelegationManager(deployments.delegationManager), - IPauserRegistry(deployments.pauserRegistry), - "1.0.0" + IPauserRegistry(deployments.pauserRegistry) ) ); @@ -294,8 +304,7 @@ library CoreDeployLib { address baseStrategyImpl = address( new StrategyBase( IStrategyManager(deployments.strategyManager), - IPauserRegistry(deployments.pauserRegistry), - "1.0.0" + IPauserRegistry(deployments.pauserRegistry) ) ); @@ -304,8 +313,7 @@ library CoreDeployLib { address strategyFactoryImpl = address( new StrategyFactory( IStrategyManager(deployments.strategyManager), - IPauserRegistry(deployments.pauserRegistry), - "1.0.0" + IPauserRegistry(deployments.pauserRegistry) ) ); @@ -338,8 +346,7 @@ library CoreDeployLib { MAX_REWARDS_DURATION: config.rewardsCoordinator.maxRewardsDuration, MAX_RETROACTIVE_LENGTH: config.rewardsCoordinator.maxRetroactiveLength, MAX_FUTURE_LENGTH: config.rewardsCoordinator.maxFutureLength, - GENESIS_REWARDS_TIMESTAMP: config.rewardsCoordinator.genesisRewardsTimestamp, - version: "1.0.0" + GENESIS_REWARDS_TIMESTAMP: config.rewardsCoordinator.genesisRewardsTimestamp }) ) ); diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index d786de1d..036aafb1 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -55,6 +55,8 @@ import {PermissionController} from import {AllocationManager} from "eigenlayer-contracts/src/contracts/core/AllocationManager.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; +import {AllocationManagerView} from + "eigenlayer-contracts/src/contracts/core/AllocationManagerView.sol"; import {BLSApkRegistryHarness} from "../harnesses/BLSApkRegistryHarness.sol"; import {EmptyContract} from "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; @@ -96,6 +98,7 @@ contract MockAVSDeployer is Test { AVSDirectory public avsDirectoryImplementation; AVSDirectoryMock public avsDirectoryMock; AllocationManagerMock public allocationManagerMock; + AllocationManagerView public allocationManagerView; AllocationManager public allocationManager; AllocationManager public allocationManagerImplementation; RewardsCoordinator public rewardsCoordinator; @@ -276,19 +279,20 @@ contract MockAVSDeployer is Test { ); IStrategy eigenStrategy = IStrategy( - new EigenStrategy( - IStrategyManager(address(strategyManagerMock)), pauserRegistry, "v0.0.1" - ) + new EigenStrategy(IStrategyManager(address(strategyManagerMock)), pauserRegistry) ); + allocationManagerView = + new AllocationManagerView(delegationMock, eigenStrategy, uint32(7 days), uint32(1 days)); + allocationManagerImplementation = new AllocationManager( + allocationManagerView, delegationMock, eigenStrategy, pauserRegistry, permissionControllerMock, uint32(7 days), // DEALLOCATION_DELAY - uint32(1 days), // ALLOCATION_CONFIGURATION_DELAY - "v0.0.1" // Added config parameter + uint32(1 days) // ALLOCATION_CONFIGURATION_DELAY ); proxyAdmin.upgrade( ITransparentUpgradeableProxy(payable(address(allocationManager))),