diff --git a/foundry.toml b/foundry.toml index fd0aac0f..a4b33112 100644 --- a/foundry.toml +++ b/foundry.toml @@ -15,7 +15,7 @@ optimizer_runs = 200 # Whether or not to use the Yul intermediate representation compilation pipeline via_ir = false # Override the Solidity version (this overrides `auto_detect_solc`) -solc_version = '0.8.12' +solc_version = '0.8.27' [etherscan] mainnet = { key = "${ETHERSCAN_API_KEY}" } diff --git a/lib/eigenlayer-contracts b/lib/eigenlayer-contracts index d8a8341c..d98c5a7d 160000 --- a/lib/eigenlayer-contracts +++ b/lib/eigenlayer-contracts @@ -1 +1 @@ -Subproject commit d8a8341c5d5c960e6da7c08a845f2584da579cf7 +Subproject commit d98c5a7df7634e25073b9a508be1a6606d7caf0c diff --git a/script/OperatorSetUpgrade.s.sol b/script/OperatorSetUpgrade.s.sol index 39158e0a..32cd80fe 100644 --- a/script/OperatorSetUpgrade.s.sol +++ b/script/OperatorSetUpgrade.s.sol @@ -12,6 +12,7 @@ import {IBLSApkRegistry} from "../src/interfaces/IBLSApkRegistry.sol"; import {IIndexRegistry} from "../src/interfaces/IIndexRegistry.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; interface IServiceManagerMigration { function getOperatorsToMigrate() @@ -46,6 +47,7 @@ contract OperatorSetUpgradeScript is Script { address public delegationManager; address public blsApkRegistry; address public indexRegistry; + address public allocationManager; function setUp() public { vm.label(DEFAULT_FORGE_SENDER, "DEFAULT FORGE SENDER"); @@ -145,7 +147,7 @@ contract OperatorSetUpgradeScript is Script { function _upgradeAvsDirectory() internal { address proxyAdmin = OperatorSetUpgradeLib.getAdmin(avsDirectory); address avsDirectoryOwner = Ownable(proxyAdmin).owner(); - AVSDirectory avsDirectoryImpl = new AVSDirectory(IDelegationManager(delegationManager)); + AVSDirectory avsDirectoryImpl = new AVSDirectory(IDelegationManager(delegationManager), 0); // TODO: config vm.startPrank(avsDirectoryOwner); OperatorSetUpgradeLib.upgrade(avsDirectory, address(avsDirectoryImpl)); @@ -211,7 +213,8 @@ contract OperatorSetUpgradeScript is Script { IAVSDirectory(avsDirectory), IRewardsCoordinator(rewardsCoordinator), IRegistryCoordinator(registryCoordinator), - IStakeRegistry(stakeRegistry) + IStakeRegistry(stakeRegistry), + IAllocationManager(allocationManager) )); address newRegistryCoordinatorImpl = address(new RegistryCoordinator( IServiceManager(serviceManager), diff --git a/src/BLSSignatureChecker.sol b/src/BLSSignatureChecker.sol index 5392289c..b3a66ae8 100644 --- a/src/BLSSignatureChecker.sol +++ b/src/BLSSignatureChecker.sol @@ -193,9 +193,11 @@ contract BLSSignatureChecker is IBLSSignatureChecker { */ { bool _staleStakesForbidden = staleStakesForbidden; - uint256 withdrawalDelayBlocks = _staleStakesForbidden - ? delegation.minWithdrawalDelayBlocks() - : 0; + /// TODO: FIX + uint256 withdrawalDelayBlocks = 0; + // uint256 withdrawalDelayBlocks = _staleStakesForbidden + // ? delegation.minWithdrawalDelayBlocks() + // : 0; for (uint256 i = 0; i < quorumNumbers.length; i++) { // If we're disallowing stale stake updates, check that each quorum's last update block diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 818f0541..c71e7278 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.12; import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; -import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IAVSDirectory, OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {ISocketUpdater} from "./interfaces/ISocketUpdater.sol"; import {IBLSApkRegistry} from "./interfaces/IBLSApkRegistry.sol"; import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol"; @@ -676,7 +676,7 @@ contract RegistryCoordinator is for (uint256 i = 0; i < quorumBytes.length; i++) { /// We need to track forceDeregistrations so we don't pass an id that was already deregistered on the AVSDirectory /// but hasnt yet been recorded in the middleware contracts - if (!avsDirectory.isMember(operator, IAVSDirectory.OperatorSet(address(serviceManager), uint8(quorumBytes[i])))){ + if (!avsDirectory.isMember(operator, OperatorSet(address(serviceManager), uint8(quorumBytes[i])))){ forceDeregistrationCount++; } operatorSetIds[i] = uint8(quorumBytes[i]); @@ -687,7 +687,7 @@ contract RegistryCoordinator is uint32[] memory filteredOperatorSetIds = new uint32[](operatorSetIds.length - forceDeregistrationCount); uint256 offset; for (uint256 i; i < operatorSetIds.length; i++){ - if (avsDirectory.isMember(operator, IAVSDirectory.OperatorSet(address(serviceManager), operatorSetIds[i]))){ + if (avsDirectory.isMember(operator, OperatorSet(address(serviceManager), operatorSetIds[i]))){ filteredOperatorSetIds[i] = operatorSetIds[i+offset]; } else { offset++; diff --git a/src/ServiceManagerBase.sol b/src/ServiceManagerBase.sol index 2fbacea2..47ac07f1 100644 --- a/src/ServiceManagerBase.sol +++ b/src/ServiceManagerBase.sol @@ -6,6 +6,7 @@ import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISi import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; +import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; import {ServiceManagerBaseStorage} from "./ServiceManagerBaseStorage.sol"; import {IServiceManager} from "./interfaces/IServiceManager.sol"; @@ -38,11 +39,10 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { _; } - function _checkRewardsInitiator() internal view { - require( - msg.sender == rewardsInitiator, - "ServiceManagerBase.onlyRewardsInitiator: caller is not the rewards initiator" - ); + /// @notice only slasher can call functions with this modifier + modifier onlySlasher() { + _checkSlasher(); + _; } /// @notice Sets the (immutable) `_registryCoordinator` address @@ -50,13 +50,15 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { IAVSDirectory __avsDirectory, IRewardsCoordinator __rewardsCoordinator, IRegistryCoordinator __registryCoordinator, - IStakeRegistry __stakeRegistry + IStakeRegistry __stakeRegistry, + IAllocationManager __allocationManager ) ServiceManagerBaseStorage( __avsDirectory, __rewardsCoordinator, __registryCoordinator, - __stakeRegistry + __stakeRegistry, + __allocationManager ) { _disableInitializers(); @@ -64,10 +66,12 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { function __ServiceManagerBase_init( address initialOwner, - address _rewardsInitiator + address _rewardsInitiator, + address _slasher ) internal virtual onlyInitializing { _transferOwnership(initialOwner); _setRewardsInitiator(_rewardsInitiator); + _setSlasher(_slasher); } /** @@ -79,6 +83,10 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { _avsDirectory.updateAVSMetadataURI(_metadataURI); } + function slashOperator(IAllocationManager.SlashingParams memory params) external onlySlasher { + _allocationManager.slashOperator(params); + } + /** * @notice Creates a new rewards submission to the EigenLayer RewardsCoordinator contract, to be split amongst the * set of stakers delegated to operators who are registered to this `avs` @@ -168,6 +176,15 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { _setRewardsInitiator(newRewardsInitiator); } + /** + * @notice Sets the slasher address + * @param newSlasher The new slasher address + * @dev only callable by the owner + */ + function setSlasher(address newSlasher) external onlyOwner { + _setSlasher(newSlasher); + } + /** * @notice Migrates the AVS to use operator sets and creates new operator set IDs. * @param operatorSetsToCreate An array of operator set IDs to create. @@ -325,6 +342,11 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { rewardsInitiator = newRewardsInitiator; } + function _setSlasher(address newSlasher) internal { + emit SlasherUpdated(slasher, newSlasher); + slasher = newSlasher; + } + /** * @notice Returns the list of strategies that the AVS supports for restaking * @dev This function is intended to be called off-chain @@ -402,4 +424,19 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage { function avsDirectory() external view override returns (address) { return address(_avsDirectory); } + + function _checkRewardsInitiator() internal view { + require( + msg.sender == rewardsInitiator, + "ServiceManagerBase.onlyRewardsInitiator: caller is not the rewards initiator" + ); + } + + + function _checkSlasher() internal view { + require( + msg.sender == slasher, + "ServiceManagerBase.onlySlasher: caller is not the slasher" + ); + } } diff --git a/src/ServiceManagerBaseStorage.sol b/src/ServiceManagerBaseStorage.sol index 4d0c1fec..71d54d98 100644 --- a/src/ServiceManagerBaseStorage.sol +++ b/src/ServiceManagerBaseStorage.sol @@ -9,6 +9,7 @@ import {IStakeRegistry} from "./interfaces/IStakeRegistry.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; +import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; /** * @title Storage variables for the `ServiceManagerBase` contract. @@ -25,6 +26,7 @@ abstract contract ServiceManagerBaseStorage is IServiceManager, OwnableUpgradeab IRewardsCoordinator internal immutable _rewardsCoordinator; IRegistryCoordinator internal immutable _registryCoordinator; IStakeRegistry internal immutable _stakeRegistry; + IAllocationManager internal immutable _allocationManager; /** * @@ -35,21 +37,26 @@ abstract contract ServiceManagerBaseStorage is IServiceManager, OwnableUpgradeab /// @notice The address of the entity that can initiate rewards address public rewardsInitiator; + /// @notice The address of the slasher account + address public slasher; + bool public migrationFinalized; - /// @notice Sets the (immutable) `_avsDirectory`, `_rewardsCoordinator`, `_registryCoordinator`, and `_stakeRegistry` addresses + /// @notice Sets the (immutable) `_avsDirectory`, `_rewardsCoordinator`, `_registryCoordinator`, `_stakeRegistry`, and `_allocationManager` addresses constructor( IAVSDirectory __avsDirectory, IRewardsCoordinator __rewardsCoordinator, IRegistryCoordinator __registryCoordinator, - IStakeRegistry __stakeRegistry + IStakeRegistry __stakeRegistry, + IAllocationManager __allocationManager ) { _avsDirectory = __avsDirectory; _rewardsCoordinator = __rewardsCoordinator; _registryCoordinator = __registryCoordinator; _stakeRegistry = __stakeRegistry; + _allocationManager = __allocationManager; } // storage gap for upgradeability - uint256[49] private __GAP; + uint256[48] private __GAP; } diff --git a/src/StakeRegistry.sol b/src/StakeRegistry.sol index ca4b55fb..9d4da097 100644 --- a/src/StakeRegistry.sol +++ b/src/StakeRegistry.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.12; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IAVSDirectory, OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import {IServiceManager} from "./interfaces/IServiceManager.sol"; import {StakeRegistryStorage, IStrategy} from "./StakeRegistryStorage.sol"; @@ -182,7 +182,7 @@ contract StakeRegistry is StakeRegistryStorage { // Query the AVSDirectory to check if the operator is directly unregistered operatorRegistered = avsDirectory.isMember( operator, - IAVSDirectory.OperatorSet(address(serviceManager), operatorSetId) + OperatorSet(address(serviceManager), operatorSetId) ); if (!hasMinimumStake || (isOperatorSetAVS && !operatorRegistered)) { @@ -491,7 +491,8 @@ contract StakeRegistry is StakeRegistryStorage { uint256 stratsLength = strategyParamsLength(quorumNumber); StrategyParams memory strategyAndMultiplier; - uint256[] memory strategyShares = delegation.getOperatorShares(operator, strategiesPerQuorum[quorumNumber]); + uint256[] memory strategyShares; + // = delegation.getDelegatableShares(operator, strategiesPerQuorum[quorumNumber]); for (uint256 i = 0; i < stratsLength; i++) { // accessing i^th StrategyParams struct for the quorumNumber strategyAndMultiplier = strategyParams[quorumNumber][i]; diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index 8807e9df..5057525e 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -4,6 +4,7 @@ pragma solidity >=0.5.0; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; import {IServiceManagerUI} from "./IServiceManagerUI.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; +import {IAllocationManagerTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; /** * @title Minimal interface for a ServiceManager-type contract that forms the single point for an AVS to push updates to EigenLayer @@ -23,7 +24,7 @@ interface IServiceManager is IServiceManagerUI { */ function createAVSRewardsSubmission(IRewardsCoordinator.RewardsSubmission[] calldata rewardsSubmissions) external; - function createOperatorSets(uint32[] memory operatorSetIds) external ; + function createOperatorSets(uint32[] memory operatorSetIds) external; /** * @notice Forwards a call to EigenLayer's AVSDirectory contract to register an operator to operator sets @@ -44,6 +45,9 @@ interface IServiceManager is IServiceManagerUI { */ function deregisterOperatorFromOperatorSets(address operator, uint32[] calldata operatorSetIds) external; + function slashOperator(IAllocationManagerTypes.SlashingParams memory params) external; + // EVENTS event RewardsInitiatorUpdated(address prevRewardsInitiator, address newRewardsInitiator); + event SlasherUpdated(address prevSlasher, address newSlasher); } diff --git a/src/libraries/SignatureCheckerLib.sol b/src/libraries/SignatureCheckerLib.sol index fa2fb137..c01fd3a7 100644 --- a/src/libraries/SignatureCheckerLib.sol +++ b/src/libraries/SignatureCheckerLib.sol @@ -1,8 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.12; -import {EIP1271SignatureUtils} from - "eigenlayer-contracts/src/contracts/libraries/EIP1271SignatureUtils.sol"; +import "@openzeppelin-upgrades/contracts/utils/cryptography/SignatureCheckerUpgradeable.sol"; /** * @title SignatureCheckerLib @@ -11,6 +10,8 @@ import {EIP1271SignatureUtils} from * validation logic to this external library. */ library SignatureCheckerLib { + error InvalidSignature(); + /** * @notice Validates a signature using EIP-1271 standard. * @param signer The address of the signer. @@ -22,6 +23,8 @@ library SignatureCheckerLib { bytes32 digestHash, bytes memory signature ) external view { - EIP1271SignatureUtils.checkSignature_EIP1271(signer, digestHash, signature); + if (!SignatureCheckerUpgradeable.isValidSignatureNow(signer, digestHash, signature)) { + revert InvalidSignature(); + } } } diff --git a/src/slashers/SimpleSlasher.sol b/src/slashers/SimpleSlasher.sol new file mode 100644 index 00000000..faa4f49b --- /dev/null +++ b/src/slashers/SimpleSlasher.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import {Initializable} from "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; +import {IServiceManager} from "../interfaces/IServiceManager.sol"; +import {SlasherStorage} from "./SlasherStorage.sol"; +import {IAllocationManagerTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; + +contract SimpleSlasher is Initializable, SlasherStorage { + function initialize(address _serviceManager) public initializer { + serviceManager = _serviceManager; + } + + function slashOperator( + address operator, + uint32 operatorSetId, + IStrategy[] memory strategies, + uint256 wadToSlash, + string memory description + ) external { + + IAllocationManagerTypes.SlashingParams memory params = IAllocationManagerTypes.SlashingParams({ + operator: operator, + operatorSetId: operatorSetId, + strategies: strategies, + wadToSlash: wadToSlash, + description: description + }); + + IServiceManager(serviceManager).slashOperator(params); + } +} diff --git a/src/slashers/SlasherStorage.sol b/src/slashers/SlasherStorage.sol new file mode 100644 index 00000000..1b3d61de --- /dev/null +++ b/src/slashers/SlasherStorage.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +contract SlasherStorage { + address public serviceManager; + + uint256[49] private __gap; +} \ No newline at end of file diff --git a/src/unaudited/ECDSAServiceManagerBase.sol b/src/unaudited/ECDSAServiceManagerBase.sol index 57326bea..3d30f451 100644 --- a/src/unaudited/ECDSAServiceManagerBase.sol +++ b/src/unaudited/ECDSAServiceManagerBase.sol @@ -238,8 +238,10 @@ abstract contract ECDSAServiceManagerBase is for (uint256 i; i < count; i++) { strategies[i] = quorum.strategies[i].strategy; } - uint256[] memory shares = IDelegationManager(delegationManager) - .getOperatorShares(_operator, strategies); + uint256[] memory shares; + // TODO: Fix + // = IDelegationManager(delegationManager) + // .getOperatorShares(_operator, strategies); uint256 activeCount; for (uint256 i; i < count; i++) { diff --git a/src/unaudited/ECDSAStakeRegistry.sol b/src/unaudited/ECDSAStakeRegistry.sol index ab4bdbeb..a8dff79a 100644 --- a/src/unaudited/ECDSAStakeRegistry.sol +++ b/src/unaudited/ECDSAStakeRegistry.sol @@ -248,10 +248,12 @@ contract ECDSAStakeRegistry is for (uint256 i; i < strategyParams.length; i++) { strategies[i] = strategyParams[i].strategy; } - uint256[] memory shares = DELEGATION_MANAGER.getOperatorShares( - _operator, - strategies - ); + uint256[] memory shares; + /// TODO: FIX + // = DELEGATION_MANAGER.getOperatorShares( + // _operator, + // strategies + // ); for (uint256 i; i < strategyParams.length; i++) { weight += shares[i] * strategyParams[i].multiplier; } diff --git a/test/harnesses/AVSDirectoryHarness.sol b/test/harnesses/AVSDirectoryHarness.sol index 99efedec..94598058 100644 --- a/test/harnesses/AVSDirectoryHarness.sol +++ b/test/harnesses/AVSDirectoryHarness.sol @@ -7,7 +7,7 @@ import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory // wrapper around the AVSDirectory contract that exposes internal functionality, for unit testing contract AVSDirectoryHarness is AVSDirectory { - constructor(IDelegationManager _delegation) AVSDirectory(_delegation) {} + constructor(IDelegationManager _delegation) AVSDirectory(_delegation, 0) {} // TODO: config update function setOperatorSaltIsSpent(address operator, bytes32 salt, bool isSpent) external { operatorSaltIsSpent[operator][salt] = isSpent; @@ -59,7 +59,7 @@ contract AVSDirectoryHarness is AVSDirectory { } function _calculateDigestHashExternal(bytes32 structHash) external view returns (bytes32) { - return _calculateDigestHash(structHash); + // return calculateOperatorSetRegistrationDigestHash(structHash); // TODO: Fix } function _calculateDomainSeparatorExternal() external view returns (bytes32) { diff --git a/test/integration/CoreRegistration.t.sol b/test/integration/CoreRegistration.t.sol index f6cbf571..b9784dc6 100644 --- a/test/integration/CoreRegistration.t.sol +++ b/test/integration/CoreRegistration.t.sol @@ -3,9 +3,10 @@ pragma solidity ^0.8.12; import "../utils/MockAVSDeployer.sol"; import { AVSDirectory } from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; -import { IAVSDirectory } from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import { IAVSDirectory, IAVSDirectoryTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import { IStrategyManager } from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import { DelegationManager } from "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; -import { IDelegationManager } from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import { IDelegationManager, IDelegationManagerTypes } from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import { RewardsCoordinator } from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; import { IRewardsCoordinator } from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; @@ -26,7 +27,7 @@ contract Test_CoreRegistration is MockAVSDeployer { _deployMockEigenLayerAndAVS(); // Deploy New DelegationManager - DelegationManager delegationManagerImplementation = new DelegationManager(strategyManagerMock, slasher, eigenPodManagerMock); + DelegationManager delegationManagerImplementation = new DelegationManager(avsDirectoryMock, IStrategyManager(address(strategyManagerMock)), eigenPodManagerMock, allocationManagerMock, 0); IStrategy[] memory initializeStrategiesToSetDelayBlocks = new IStrategy[](0); uint256[] memory initializeWithdrawalDelayBlocks = new uint256[](0); delegationManager = DelegationManager( @@ -48,7 +49,7 @@ contract Test_CoreRegistration is MockAVSDeployer { ); // Deploy New AVS Directory - AVSDirectory avsDirectoryImplementation = new AVSDirectory(delegationManager); + AVSDirectory avsDirectoryImplementation = new AVSDirectory(delegationManager, 0); // TODO: Fix Config avsDirectory = AVSDirectory( address( new TransparentUpgradeableProxy( @@ -72,7 +73,8 @@ contract Test_CoreRegistration is MockAVSDeployer { avsDirectory, rewardsCoordinatorMock, registryCoordinator, - stakeRegistry + stakeRegistry, + allocationManager ); registryCoordinatorImplementation = new RegistryCoordinatorHarness( @@ -102,11 +104,13 @@ contract Test_CoreRegistration is MockAVSDeployer { // Register operator to EigenLayer cheats.prank(operator); delegationManager.registerAsOperator( - IDelegationManager.OperatorDetails({ + IDelegationManagerTypes.OperatorDetails({ __deprecated_earningsReceiver: operator, delegationApprover: address(0), - stakerOptOutWindowBlocks: 0 + __deprecated_stakerOptOutWindowBlocks: 0 }), + // TODO: fix or parameterize + 0, emptyStringForMetadataURI ); @@ -137,8 +141,8 @@ contract Test_CoreRegistration is MockAVSDeployer { registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams, operatorSignature); // Check operator is registered - IAVSDirectory.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); - assertEq(uint8(operatorStatus), uint8(IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED)); + IAVSDirectoryTypes.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); + assertEq(uint8(operatorStatus), uint8(IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED)); } function test_deregisterOperator_coreStateChanges() public { @@ -151,8 +155,8 @@ contract Test_CoreRegistration is MockAVSDeployer { registryCoordinator.deregisterOperator(quorumNumbers); // Check operator is deregistered - IAVSDirectory.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); - assertEq(uint8(operatorStatus), uint8(IAVSDirectory.OperatorAVSRegistrationStatus.UNREGISTERED)); + IAVSDirectoryTypes.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); + assertEq(uint8(operatorStatus), uint8(IAVSDirectoryTypes.OperatorAVSRegistrationStatus.UNREGISTERED)); } function test_deregisterOperator_notGloballyDeregistered() public { @@ -167,8 +171,8 @@ contract Test_CoreRegistration is MockAVSDeployer { registryCoordinator.deregisterOperator(quorumNumbers); // Check operator is still registered - IAVSDirectory.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); - assertEq(uint8(operatorStatus), uint8(IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED)); + IAVSDirectoryTypes.OperatorAVSRegistrationStatus operatorStatus = avsDirectory.avsOperatorStatus(address(serviceManager), operator); + assertEq(uint8(operatorStatus), uint8(IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED)); } function test_setMetadataURI_fail_notServiceManagerOwner() public { diff --git a/test/integration/IntegrationBase.t.sol b/test/integration/IntegrationBase.t.sol index c9695d70..7a0265f9 100644 --- a/test/integration/IntegrationBase.t.sol +++ b/test/integration/IntegrationBase.t.sol @@ -166,15 +166,15 @@ abstract contract IntegrationBase is IntegrationConfig { /// AVSDirectory: function assert_NotRegisteredToAVS(User operator, string memory err) internal { - IAVSDirectory.OperatorAVSRegistrationStatus status = avsDirectory.avsOperatorStatus(address(serviceManager), address(operator)); + IAVSDirectoryTypes.OperatorAVSRegistrationStatus status = avsDirectory.avsOperatorStatus(address(serviceManager), address(operator)); - assertTrue(status == IAVSDirectory.OperatorAVSRegistrationStatus.UNREGISTERED, err); + assertTrue(status == IAVSDirectoryTypes.OperatorAVSRegistrationStatus.UNREGISTERED, err); } function assert_IsRegisteredToAVS(User operator, string memory err) internal { IAVSDirectory.OperatorAVSRegistrationStatus status = avsDirectory.avsOperatorStatus(address(serviceManager), address(operator)); - assertTrue(status == IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED, err); + assertTrue(status == IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED, err); } /******************************************************************************* @@ -591,7 +591,7 @@ abstract contract IntegrationBase is IntegrationConfig { function assert_Snap_Removed_OperatorShares( User operator, IStrategy[] memory strategies, - uint[] memory removedShares, + uint256[] memory removedShares, string memory err ) internal { uint[] memory curShares = _getOperatorShares(operator, strategies); @@ -773,7 +773,7 @@ abstract contract IntegrationBase is IntegrationConfig { for (uint i = 0; i < strategies.length; i++) { IStrategy strat = strategies[i]; - curShares[i] = strategyManager.stakerStrategyShares(address(staker), strat); + curShares[i] = strategyManager.stakerDepositShares(address(staker), strat); } return curShares; diff --git a/test/integration/IntegrationChecks.t.sol b/test/integration/IntegrationChecks.t.sol index b54f8568..67ee38f5 100644 --- a/test/integration/IntegrationChecks.t.sol +++ b/test/integration/IntegrationChecks.t.sol @@ -245,7 +245,7 @@ contract IntegrationChecks is IntegrationBase { User operator, bytes memory quorums, IStrategy[] memory strategies, - uint[] memory shares + uint256[] memory shares ) internal { _log("check_Withdraw_State", operator); diff --git a/test/integration/IntegrationDeployer.t.sol b/test/integration/IntegrationDeployer.t.sol index ee3722a7..7b9705f9 100644 --- a/test/integration/IntegrationDeployer.t.sol +++ b/test/integration/IntegrationDeployer.t.sol @@ -14,9 +14,9 @@ import "@openzeppelin/contracts/utils/Strings.sol"; // Core contracts import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; -import "eigenlayer-contracts/src/contracts/core/Slasher.sol"; import "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; import "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.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"; import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; @@ -51,10 +51,10 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { EigenPodManager eigenPodManager; RewardsCoordinator rewardsCoordinator; PauserRegistry pauserRegistry; - Slasher slasher; IBeacon eigenPodBeacon; EigenPod pod; ETHPOSDepositMock ethPOSDeposit; + AllocationManager allocationManager; // Base strategy implementation in case we want to create more strategies later StrategyBase baseStrategyImplementation; @@ -131,17 +131,18 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") ) ); - slasher = Slasher( + eigenPodManager = EigenPodManager( address( new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") ) ); - eigenPodManager = EigenPodManager( + avsDirectory = AVSDirectory( address( new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") ) ); - avsDirectory = AVSDirectory( + + allocationManager = AllocationManager( address( new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") ) @@ -161,14 +162,13 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs DelegationManager delegationImplementation = - new DelegationManager(strategyManager, slasher, eigenPodManager); + new DelegationManager(avsDirectory, strategyManager, eigenPodManager, allocationManager, 0); StrategyManager strategyManagerImplementation = - new StrategyManager(delegationManager, eigenPodManager, slasher); - Slasher slasherImplementation = new Slasher(strategyManager, delegationManager); + new StrategyManager(delegationManager); EigenPodManager eigenPodManagerImplementation = new EigenPodManager( - ethPOSDeposit, eigenPodBeacon, strategyManager, slasher, delegationManager + ethPOSDeposit, eigenPodBeacon, strategyManager, delegationManager ); - AVSDirectory avsDirectoryImplemntation = new AVSDirectory(delegationManager); + AVSDirectory avsDirectoryImplemntation = new AVSDirectory(delegationManager, 0); // TODO: fix config // RewardsCoordinator rewardsCoordinatorImplementation = new RewardsCoordinator( // delegationManager, // IStrategyManager(address(strategyManager)), @@ -208,17 +208,6 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { 0 // initialPausedStatus ) ); - // Slasher - proxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(slasher))), - address(slasherImplementation), - abi.encodeWithSelector( - Slasher.initialize.selector, - eigenLayerReputedMultisig, - pauserRegistry, - 0 // initialPausedStatus - ) - ); // EigenPodManager proxyAdmin.upgradeAndCall( TransparentUpgradeableProxy(payable(address(eigenPodManager))), @@ -312,7 +301,8 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { IAVSDirectory(avsDirectory), rewardsCoordinator, IRegistryCoordinator(registryCoordinator), - stakeRegistry + stakeRegistry, + allocationManager ); proxyAdmin.upgrade( @@ -337,7 +327,8 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { serviceManager.initialize({ initialOwner: registryCoordinatorOwner, - rewardsInitiator: address(msg.sender) + rewardsInitiator: address(msg.sender), + slasher: address(msg.sender) }); RegistryCoordinator registryCoordinatorImplementation = @@ -389,7 +380,7 @@ abstract contract IntegrationDeployer is Test, IUserDeployer { strategies[0] = strategy; cheats.prank(strategyManager.strategyWhitelister()); strategyManager.addStrategiesToDepositWhitelist( - strategies, thirdPartyTransfersForbiddenValues + strategies ); // Add to allStrats diff --git a/test/integration/User.t.sol b/test/integration/User.t.sol index 9e5e5990..ff31a7ed 100644 --- a/test/integration/User.t.sol +++ b/test/integration/User.t.sol @@ -11,6 +11,7 @@ import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; // Core import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; import "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; @@ -243,13 +244,13 @@ contract User is Test { function registerAsOperator() public createSnapshot virtual { _log("registerAsOperator (core)"); - IDelegationManager.OperatorDetails memory details = IDelegationManager.OperatorDetails({ + IDelegationManagerTypes.OperatorDetails memory details = IDelegationManagerTypes.OperatorDetails({ __deprecated_earningsReceiver: address(this), delegationApprover: address(0), - stakerOptOutWindowBlocks: 0 + __deprecated_stakerOptOutWindowBlocks: 0 }); - delegationManager.registerAsOperator(details, NAME); + delegationManager.registerAsOperator(details,0, NAME); } // Deposit LSTs into the StrategyManager. This setup does not use the EPMgr or native ETH. @@ -266,13 +267,15 @@ contract User is Test { } } - function exitEigenlayer() public createSnapshot virtual returns (IStrategy[] memory, uint[] memory) { + function exitEigenlayer() public createSnapshot virtual returns (IStrategy[] memory, uint256[] memory) { _log("exitEigenlayer (core)"); - (IStrategy[] memory strategies, uint[] memory shares) = delegationManager.getDelegatableShares(address(this)); + IStrategy[] memory strategies; + uint256[] memory shares; + // = delegationManager.getDelegatableShares(address(this)); // TODO: Fix - IDelegationManager.QueuedWithdrawalParams[] memory params = new IDelegationManager.QueuedWithdrawalParams[](1); - params[0] = IDelegationManager.QueuedWithdrawalParams({ + IDelegationManagerTypes.QueuedWithdrawalParams[] memory params = new IDelegationManager.QueuedWithdrawalParams[](1); + params[0] = IDelegationManagerTypes.QueuedWithdrawalParams({ strategies: strategies, shares: shares, withdrawer: address(this) diff --git a/test/integration/tests/NonFull_Register_CoreBalanceChange_Update.t.sol b/test/integration/tests/NonFull_Register_CoreBalanceChange_Update.t.sol index 43daf518..a4ffe3e6 100644 --- a/test/integration/tests/NonFull_Register_CoreBalanceChange_Update.t.sol +++ b/test/integration/tests/NonFull_Register_CoreBalanceChange_Update.t.sol @@ -118,7 +118,7 @@ contract Integration_NonFull_Register_CoreBalanceChange_Update is IntegrationChe check_Register_State(operator, quorums); // 2. (core) queue full withdrawal - (IStrategy[] memory strategies, uint[] memory shares) = operator.exitEigenlayer(); + (IStrategy[] memory strategies, uint256[] memory shares) = operator.exitEigenlayer(); check_Withdraw_State(operator, quorums, strategies, shares); // 3. Update stakes @@ -151,7 +151,7 @@ contract Integration_NonFull_Register_CoreBalanceChange_Update is IntegrationChe check_Register_State(operator, quorums); // 2. (core) queue full withdrawal - (IStrategy[] memory strategies, uint[] memory shares) = operator.exitEigenlayer(); + (IStrategy[] memory strategies, uint256[] memory shares) = operator.exitEigenlayer(); check_Withdraw_State(operator, quorums, strategies, shares); // 3. Deregister from all quorums diff --git a/test/mocks/AVSDirectoryMock.sol b/test/mocks/AVSDirectoryMock.sol index 46bfb5db..a6bf2a3c 100644 --- a/test/mocks/AVSDirectoryMock.sol +++ b/test/mocks/AVSDirectoryMock.sol @@ -1,194 +1,173 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.12; -import { - IAVSDirectory, - ISignatureUtils -} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IAVSDirectory, OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; contract AVSDirectoryMock is IAVSDirectory { - /** - * @notice Called by an AVS to create a list of new operatorSets. - * - * @param operatorSetIds The IDs of the operator set to initialize. - * - * @dev msg.sender must be the AVS. - * @dev The AVS may create operator sets before it becomes an operator set AVS. - */ - function createOperatorSets(uint32[] calldata operatorSetIds) external {} - - /** - * @notice Sets the AVS as an operator set AVS, preventing legacy M2 operator registrations. - * - * @dev msg.sender must be the AVS. - */ - function becomeOperatorSetAVS() external {} - - /** - * @notice Called by an AVS to migrate operators that have a legacy M2 registration to operator sets. - * - * @param operators The list of operators to migrate - * @param operatorSetIds The list of operatorSets to migrate the operators to - * - * @dev The msg.sender used is the AVS - * @dev The operator can only be migrated at most once per AVS - * @dev The AVS can no longer register operators via the legacy M2 registration path once it begins migration - * @dev The operator is deregistered from the M2 legacy AVS once migrated - */ - function migrateOperatorsToOperatorSets( - address[] calldata operators, - uint32[][] calldata operatorSetIds - ) external {} - - /** - * @notice Called by AVSs to add an operator to list of operatorSets. - * - * @param operator The address of the operator to be added to the operator set. - * @param operatorSetIds The IDs of the operator sets. - * @param operatorSignature The signature of the operator on their intent to register. - * - * @dev msg.sender is used as the AVS. - * @dev The operator must not have a pending deregistration from the operator set. - */ - function registerOperatorToOperatorSets( - address operator, - uint32[] calldata operatorSetIds, - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature - ) external {} - - /** - * @notice Called by AVSs to remove an operator from an operator set. - * - * @param operator The address of the operator to be removed from the operator set. - * @param operatorSetIds The IDs of the operator sets. - * - * @dev msg.sender is used as the AVS. - */ - function deregisterOperatorFromOperatorSets( - address operator, - uint32[] calldata operatorSetIds - ) external {} - - /** - * @notice Called by an operator to deregister from an operator set - * - * @param operator The operator to deregister from the operatorSets. - * @param avs The address of the AVS to deregister the operator from. - * @param operatorSetIds The IDs of the operator sets. - * @param operatorSignature the signature of the operator on their intent to deregister or empty if the operator itself is calling - * - * @dev if the operatorSignature is empty, the caller must be the operator - * @dev this will likely only be called in case the AVS contracts are in a state that prevents operators from deregistering - */ - function forceDeregisterFromOperatorSets( - address operator, - address avs, - uint32[] calldata operatorSetIds, - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature - ) external {} - - /** - * @notice Called by an avs to register an operator with the avs. - * @param operator The address of the operator to register. - * @param operatorSignature The signature, salt, and expiry of the operator's signature. - */ - function registerOperatorToAVS( - address operator, - ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature - ) external {} - - /** - * @notice Called by an avs to deregister an operator with the avs. - * @param operator The address of the operator to deregister. - */ - function deregisterOperatorFromAVS(address operator) external {} - - /** - * @notice Called by an AVS to emit an `AVSMetadataURIUpdated` event indicating the information has updated. - * @param metadataURI The URI for metadata associated with an AVS - * @dev Note that the `metadataURI` is *never stored * and is only emitted in the `AVSMetadataURIUpdated` event - */ - function updateAVSMetadataURI(string calldata metadataURI) external {} - - /** - * @notice Called by an operator to cancel a salt that has been used to register with an AVS. - * - * @param salt A unique and single use value associated with the approver signature. - */ - function cancelSalt(bytes32 salt) external {} - - /** - * @notice Returns whether or not the salt has already been used by the operator. - * @dev Salts is used in the `registerOperatorToAVS` function. - */ - function operatorSaltIsSpent(address operator, bytes32 salt) external view returns (bool) {} - - function isMember( - address avs, - address operator, - uint32 operatorSetId - ) external view returns (bool) {} - - /** - * @notice Calculates the digest hash to be signed by an operator to register with an AVS - * @param operator The account registering as an operator - * @param avs The AVS the operator is registering to - * @param salt A unique and single use value associated with the approver signature. - * @param expiry Time after which the approver's signature becomes invalid - */ - function calculateOperatorAVSRegistrationDigestHash( - address operator, - address avs, - bytes32 salt, - uint256 expiry - ) external view returns (bytes32) {} - - /** - * @notice Calculates the digest hash to be signed by an operator to register with an operator set. - * - * @param avs The AVS that operator is registering to operator sets for. - * @param operatorSetIds An array of operator set IDs the operator is registering to. - * @param salt A unique and single use value associated with the approver signature. - * @param expiry Time after which the approver's signature becomes invalid. - */ - function calculateOperatorSetRegistrationDigestHash( - address avs, - uint32[] calldata operatorSetIds, - bytes32 salt, - uint256 expiry - ) external view returns (bytes32) {} - - /** - * @notice Calculates the digest hash to be signed by an operator to force deregister from an operator set. - * - * @param avs The AVS that operator is deregistering from. - * @param operatorSetIds An array of operator set IDs the operator is deregistering from. - * @param salt A unique and single use value associated with the approver signature. - * @param expiry Time after which the approver's signature becomes invalid. - */ - function calculateOperatorSetForceDeregistrationTypehash( - address avs, - uint32[] calldata operatorSetIds, - bytes32 salt, - uint256 expiry - ) external view returns (bytes32) {} - - /// @notice Getter function for the current EIP-712 domain separator for this contract. - /// @dev The domain separator will change in the event of a fork that changes the ChainID. - function domainSeparator() external view returns (bytes32) {} - - /// @notice The EIP-712 typehash for the Registration struct used by the contract - function OPERATOR_AVS_REGISTRATION_TYPEHASH() external view returns (bytes32) {} - - /// @notice The EIP-712 typehash for the OperatorSetRegistration struct used by the contract. - function OPERATOR_SET_REGISTRATION_TYPEHASH() external view returns (bytes32) {} - - function isOperatorSetAVS(address avs) external view returns (bool) {} - - function isOperatorSet(address avs, uint32 operatorSetId) external view returns (bool) {} - - function isMember( - address operator, - OperatorSet memory operatorSet - ) external view returns (bool) {} -} + function createOperatorSets( + uint32[] calldata operatorSetIds + ) external {} + + function becomeOperatorSetAVS() external {} + + function migrateOperatorsToOperatorSets( + address[] calldata operators, + uint32[][] calldata operatorSetIds + ) external {} + + function registerOperatorToOperatorSets( + address operator, + uint32[] calldata operatorSetIds, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external {} + + function deregisterOperatorFromOperatorSets( + address operator, + uint32[] calldata operatorSetIds + ) external {} + + function forceDeregisterFromOperatorSets( + address operator, + address avs, + uint32[] calldata operatorSetIds, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external {} + + function registerOperatorToAVS( + address operator, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external {} + + function deregisterOperatorFromAVS(address operator) external {} + + function updateAVSMetadataURI( + string calldata metadataURI + ) external {} + + function cancelSalt(bytes32 salt) external {} + + function operatorSaltIsSpent( + address operator, + bytes32 salt + ) external view returns (bool) {} + + function isMember( + address operator, + OperatorSet memory operatorSet + ) external view returns (bool) {} + + function isOperatorSlashable( + address operator, + OperatorSet memory operatorSet + ) external view returns (bool) {} + + function isOperatorSetAVS( + address avs + ) external view returns (bool) {} + + function isOperatorSet( + address avs, + uint32 operatorSetId + ) external view returns (bool) {} + + function isOperatorSetBatch( + OperatorSet[] calldata operatorSets + ) external view returns (bool) {} + + function operatorSetsMemberOfAtIndex( + address operator, + uint256 index + ) external view returns (OperatorSet memory) {} + + function operatorSetMemberAtIndex( + OperatorSet memory operatorSet, + uint256 index + ) external view returns (address) {} + + function getOperatorSetsOfOperator( + address operator, + uint256 start, + uint256 length + ) external view returns (OperatorSet[] memory operatorSets) {} + + function getOperatorsInOperatorSet( + OperatorSet memory operatorSet, + uint256 start, + uint256 length + ) external view returns (address[] memory operators) {} + + function getNumOperatorsInOperatorSet( + OperatorSet memory operatorSet + ) external view returns (uint256) {} + + function inTotalOperatorSets( + address operator + ) external view returns (uint256) {} + + function calculateOperatorAVSRegistrationDigestHash( + address operator, + address avs, + bytes32 salt, + uint256 expiry + ) external view returns (bytes32) {} + + function calculateOperatorSetRegistrationDigestHash( + address avs, + uint32[] calldata operatorSetIds, + bytes32 salt, + uint256 expiry + ) external view returns (bytes32) {} + + function calculateOperatorSetForceDeregistrationTypehash( + address avs, + uint32[] calldata operatorSetIds, + bytes32 salt, + uint256 expiry + ) external view returns (bytes32) {} + + function OPERATOR_AVS_REGISTRATION_TYPEHASH() + external + view + returns (bytes32) + {} + + function OPERATOR_SET_REGISTRATION_TYPEHASH() + external + view + returns (bytes32) + {} + + function operatorSetStatus( + address avs, + address operator, + uint32 operatorSetId + ) + external + view + returns (bool registered, uint32 lastDeregisteredTimestamp) + {} + + function getNumOperatorSetsOfOperator( + address operator + ) external view returns (uint256) {} + + function getStrategiesInOperatorSet( + OperatorSet memory operatorSet + ) external view returns (IStrategy[] memory) {} + + function initialize( + address initialOwner, + IPauserRegistry _pauserRegistry, + uint256 initialPausedStatus + ) external {} + + function removeStrategiesFromOperatorSet( + uint32 operatorSetId, + IStrategy[] calldata strategies + ) external {} + + function addStrategiesToOperatorSet(uint32 operatorSetId, IStrategy[] calldata strategies) external {} +} \ No newline at end of file diff --git a/test/mocks/AllocationManagerMock.sol b/test/mocks/AllocationManagerMock.sol new file mode 100644 index 00000000..1436882e --- /dev/null +++ b/test/mocks/AllocationManagerMock.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import {IAllocationManager} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; +import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; +import {OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; + +contract AllocationManagerMock is IAllocationManager { + function initialize( + address initialOwner, + IPauserRegistry _pauserRegistry, + uint256 initialPausedStatus + ) external override {} + + function slashOperator(SlashingParams calldata params) external override {} + + function modifyAllocations( + MagnitudeAllocation[] calldata allocations + ) external override {} + + function clearDeallocationQueue( + address operator, + IStrategy[] calldata strategies, + uint16[] calldata numToComplete + ) external override {} + + function setAllocationDelay( + address operator, + uint32 delay + ) external override {} + + function setAllocationDelay(uint32 delay) external override {} + + function getAllocationInfo( + address operator, + IStrategy strategy + ) + external + view + override + returns (OperatorSet[] memory, MagnitudeInfo[] memory) + {} + + function getAllocationInfo( + address operator, + IStrategy strategy, + OperatorSet[] calldata operatorSets + ) external view override returns (MagnitudeInfo[] memory) {} + + function getAllocationInfo( + OperatorSet calldata operatorSet, + IStrategy[] calldata strategies, + address[] calldata operators + ) external view override returns (MagnitudeInfo[][] memory) {} + + function getAllocatableMagnitude( + address operator, + IStrategy strategy + ) external view override returns (uint64) {} + + function getMaxMagnitudes( + address operator, + IStrategy[] calldata strategies + ) external view override returns (uint64[] memory) {} + + function getMaxMagnitudesAtTimestamp( + address operator, + IStrategy[] calldata strategies, + uint32 timestamp + ) external view override returns (uint64[] memory) {} + + function getAllocationDelay( + address operator + ) external view override returns (bool isSet, uint32 delay) {} + + function getMinDelegatedAndSlashableOperatorShares( + OperatorSet calldata operatorSet, + address[] calldata operators, + IStrategy[] calldata strategies, + uint32 beforeTimestamp + ) external view override returns (uint256[][] memory, uint256[][] memory) {} +} \ No newline at end of file diff --git a/test/mocks/DelegationMock.sol b/test/mocks/DelegationMock.sol index 88cd9d20..9743fb14 100644 --- a/test/mocks/DelegationMock.sol +++ b/test/mocks/DelegationMock.sol @@ -5,199 +5,325 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IDelegationManager} 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"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; +import {SlashingLib} from "eigenlayer-contracts/src/contracts/libraries/SlashingLib.sol"; contract DelegationMock is IDelegationManager { - mapping(address => bool) public isOperator; - mapping(address => mapping(IStrategy => uint256)) public operatorShares; - - function setIsOperator(address operator, bool _isOperatorReturnValue) external { - isOperator[operator] = _isOperatorReturnValue; - } - - /// @notice returns the total number of shares in `strategy` that are delegated to `operator`. - function setOperatorShares(address operator, IStrategy strategy, uint256 shares) external { - operatorShares[operator][strategy] = shares; - } - - mapping (address => address) public delegatedTo; - - function registerAsOperator(OperatorDetails calldata /*registeringOperatorDetails*/, string calldata /*metadataURI*/) external pure {} - - function updateOperatorMetadataURI(string calldata /*metadataURI*/) external pure {} - - function updateAVSMetadataURI(string calldata /*metadataURI*/) external pure {} - - function delegateTo(address operator, SignatureWithExpiry memory /*approverSignatureAndExpiry*/, bytes32 /*approverSalt*/) external { - delegatedTo[msg.sender] = operator; - } - - function modifyOperatorDetails(OperatorDetails calldata /*newOperatorDetails*/) external pure {} - - function delegateToBySignature( - address /*staker*/, - address /*operator*/, - SignatureWithExpiry memory /*stakerSignatureAndExpiry*/, - SignatureWithExpiry memory /*approverSignatureAndExpiry*/, - bytes32 /*approverSalt*/ - ) external pure {} - - function undelegate(address staker) external returns (bytes32[] memory withdrawalRoot) { - delegatedTo[staker] = address(0); - return withdrawalRoot; - } - - function increaseDelegatedShares(address /*staker*/, IStrategy /*strategy*/, uint256 /*shares*/) external pure {} - - function decreaseDelegatedShares( - address /*staker*/, - IStrategy /*strategy*/, - uint256 /*shares*/ - ) external pure {} - - function operatorDetails(address operator) external pure returns (OperatorDetails memory) { - OperatorDetails memory returnValue = OperatorDetails({ - __deprecated_earningsReceiver: operator, - delegationApprover: operator, - stakerOptOutWindowBlocks: 0 - }); - return returnValue; - } - - function beaconChainETHStrategy() external pure returns (IStrategy) {} - - function earningsReceiver(address operator) external pure returns (address) { - return operator; - } - - function delegationApprover(address operator) external pure returns (address) { - return operator; - } - - function stakerOptOutWindowBlocks(address /*operator*/) external pure returns (uint256) { - return 0; - } - - function minWithdrawalDelayBlocks() external view returns (uint256) { - return 50400; - } - - /** - * @notice Minimum delay enforced by this contract per Strategy for completing queued withdrawals. Measured in blocks, and adjustable by this contract's owner, - * up to a maximum of `MAX_WITHDRAWAL_DELAY_BLOCKS`. Minimum value is 0 (i.e. no delay enforced). - */ - function strategyWithdrawalDelayBlocks(IStrategy /*strategy*/) external view returns (uint256) { - return 0; - } - - function getOperatorShares( - address operator, - IStrategy[] memory strategies - ) external view returns (uint256[] memory) { - uint256[] memory shares = new uint256[](strategies.length); - for (uint256 i = 0; i < strategies.length; ++i) { - shares[i] = operatorShares[operator][strategies[i]]; - } - return shares; - } - - function getWithdrawalDelay(IStrategy[] calldata /*strategies*/) public view returns (uint256) { - return 0; - } - - function isDelegated(address staker) external view returns (bool) { - return (delegatedTo[staker] != address(0)); - } - - function isNotDelegated(address /*staker*/) external pure returns (bool) {} - - // function isOperator(address /*operator*/) external pure returns (bool) {} - - function stakerNonce(address /*staker*/) external pure returns (uint256) {} - - function delegationApproverSaltIsSpent(address /*delegationApprover*/, bytes32 /*salt*/) external pure returns (bool) {} - - function calculateCurrentStakerDelegationDigestHash(address /*staker*/, address /*operator*/, uint256 /*expiry*/) external view returns (bytes32) {} - - function calculateStakerDelegationDigestHash(address /*staker*/, uint256 /*stakerNonce*/, address /*operator*/, uint256 /*expiry*/) external view returns (bytes32) {} - - function calculateDelegationApprovalDigestHash( - address /*staker*/, - address /*operator*/, - address /*_delegationApprover*/, - bytes32 /*approverSalt*/, - uint256 /*expiry*/ - ) external view returns (bytes32) {} - - function calculateStakerDigestHash(address /*staker*/, address /*operator*/, uint256 /*expiry*/) - external pure returns (bytes32 stakerDigestHash) {} - - function calculateApproverDigestHash(address /*staker*/, address /*operator*/, uint256 /*expiry*/) - external pure returns (bytes32 approverDigestHash) {} - - function calculateOperatorAVSRegistrationDigestHash(address /*operator*/, address /*avs*/, bytes32 /*salt*/, uint256 /*expiry*/) - external pure returns (bytes32 digestHash) {} - - function DOMAIN_TYPEHASH() external view returns (bytes32) {} - - function STAKER_DELEGATION_TYPEHASH() external view returns (bytes32) {} - - function DELEGATION_APPROVAL_TYPEHASH() external view returns (bytes32) {} - - function domainSeparator() external view returns (bytes32) {} - - function cumulativeWithdrawalsQueued(address staker) external view returns (uint256) {} - - function calculateWithdrawalRoot(Withdrawal memory withdrawal) external pure returns (bytes32) {} - - function operatorSaltIsSpent(address avs, bytes32 salt) external view returns (bool) {} - - function queueWithdrawals( - QueuedWithdrawalParams[] calldata queuedWithdrawalParams - ) external returns (bytes32[] memory) {} - - function completeQueuedWithdrawal( - Withdrawal calldata withdrawal, - IERC20[] calldata tokens, - uint256 middlewareTimesIndex, - bool receiveAsTokens - ) external {} - - function completeQueuedWithdrawals( - Withdrawal[] calldata withdrawals, - IERC20[][] calldata tokens, - uint256[] calldata middlewareTimesIndexes, - bool[] calldata receiveAsTokens - ) external {} - - // onlyDelegationManager functions in StrategyManager - function addShares( - IStrategyManager strategyManager, - address staker, - IERC20 token, - IStrategy strategy, - uint256 shares - ) external { - strategyManager.addShares(staker, token, strategy, shares); - } - - function removeShares( - IStrategyManager strategyManager, - address staker, - IStrategy strategy, - uint256 shares - ) external { - strategyManager.removeShares(staker, strategy, shares); - } - - function withdrawSharesAsTokens( - IStrategyManager strategyManager, - address recipient, - IStrategy strategy, - uint256 shares, - IERC20 token - ) external { - strategyManager.withdrawSharesAsTokens(recipient, strategy, shares, token); + using SlashingLib for uint256; + + mapping(address => bool) public isOperator; + mapping(address => mapping(IStrategy => uint256)) public operatorShares; + + function setIsOperator( + address operator, + bool _isOperatorReturnValue + ) external { + isOperator[operator] = _isOperatorReturnValue; + } + + /// @notice returns the total number of shares in `strategy` that are delegated to `operator`. + function setOperatorShares( + address operator, + IStrategy strategy, + uint256 shares + ) external { + operatorShares[operator][strategy] = shares; + } + + mapping(address => address) public delegatedTo; + + function registerAsOperator( + OperatorDetails calldata /*registeringOperatorDetails*/, + string calldata /*metadataURI*/ + ) external pure {} + + function updateOperatorMetadataURI( + string calldata /*metadataURI*/ + ) external pure {} + + function updateAVSMetadataURI( + string calldata /*metadataURI*/ + ) external pure {} + + function delegateTo( + address operator, + SignatureWithExpiry memory /*approverSignatureAndExpiry*/, + bytes32 /*approverSalt*/ + ) external { + delegatedTo[msg.sender] = operator; + } + + function modifyOperatorDetails( + OperatorDetails calldata /*newOperatorDetails*/ + ) external pure {} + + function delegateToBySignature( + address /*staker*/, + address /*operator*/, + SignatureWithExpiry memory /*stakerSignatureAndExpiry*/, + SignatureWithExpiry memory /*approverSignatureAndExpiry*/, + bytes32 /*approverSalt*/ + ) external pure {} + + function undelegate( + address staker + ) external returns (bytes32[] memory withdrawalRoot) { + delegatedTo[staker] = address(0); + return withdrawalRoot; + } + + function increaseDelegatedShares( + address /*staker*/, + IStrategy /*strategy*/, + uint256 /*shares*/ + ) external pure {} + + function operatorDetails( + address operator + ) external pure returns (OperatorDetails memory) { + OperatorDetails memory returnValue = OperatorDetails({ + __deprecated_earningsReceiver: operator, + delegationApprover: operator, + __deprecated_stakerOptOutWindowBlocks: 0 + }); + return returnValue; + } + + function beaconChainETHStrategy() external pure returns (IStrategy) {} + + function earningsReceiver(address operator) external pure returns (address) { + return operator; + } + + function delegationApprover( + address operator + ) external pure returns (address) { + return operator; + } + + function stakerOptOutWindowBlocks( + address /*operator*/ + ) external pure returns (uint256) { + return 0; + } + + function minWithdrawalDelayBlocks() external view returns (uint256) { + return 50400; + } + + /** + * @notice Minimum delay enforced by this contract per Strategy for completing queued withdrawals. Measured in blocks, and adjustable by this contract's owner, + * up to a maximum of `MAX_WITHDRAWAL_DELAY_BLOCKS`. Minimum value is 0 (i.e. no delay enforced). + */ + function strategyWithdrawalDelayBlocks( + IStrategy /*strategy*/ + ) external view returns (uint256) { + return 0; + } + + function getOperatorShares( + address operator, + IStrategy[] memory strategies + ) external view returns (uint256[] memory) { + uint256[] memory shares = new uint256[](strategies.length); + for (uint256 i = 0; i < strategies.length; ++i) { + shares[i] = operatorShares[operator][strategies[i]]; } + return shares; + } + + function getWithdrawalDelay( + IStrategy[] calldata /*strategies*/ + ) public view returns (uint256) { + return 0; + } + + function isDelegated(address staker) external view returns (bool) { + return (delegatedTo[staker] != address(0)); + } + + function isNotDelegated(address /*staker*/) external pure returns (bool) {} + + // function isOperator(address /*operator*/) external pure returns (bool) {} + + function stakerNonce(address /*staker*/) external pure returns (uint256) {} + + function delegationApproverSaltIsSpent( + address /*delegationApprover*/, + bytes32 /*salt*/ + ) external pure returns (bool) {} + + function calculateCurrentStakerDelegationDigestHash( + address /*staker*/, + address /*operator*/, + uint256 /*expiry*/ + ) external view returns (bytes32) {} + + function calculateStakerDelegationDigestHash( + address /*staker*/, + uint256 /*stakerNonce*/, + address /*operator*/, + uint256 /*expiry*/ + ) external view returns (bytes32) {} + + function calculateDelegationApprovalDigestHash( + address /*staker*/, + address /*operator*/, + address /*_delegationApprover*/, + bytes32 /*approverSalt*/, + uint256 /*expiry*/ + ) external view returns (bytes32) {} + + function calculateStakerDigestHash( + address /*staker*/, + address /*operator*/, + uint256 /*expiry*/ + ) external pure returns (bytes32 stakerDigestHash) {} + + function calculateApproverDigestHash( + address /*staker*/, + address /*operator*/, + uint256 /*expiry*/ + ) external pure returns (bytes32 approverDigestHash) {} + + function calculateOperatorAVSRegistrationDigestHash( + address /*operator*/, + address /*avs*/, + bytes32 /*salt*/, + uint256 /*expiry*/ + ) external pure returns (bytes32 digestHash) {} + + function DOMAIN_TYPEHASH() external view returns (bytes32) {} + + function STAKER_DELEGATION_TYPEHASH() external view returns (bytes32) {} + + function DELEGATION_APPROVAL_TYPEHASH() external view returns (bytes32) {} + + function domainSeparator() external view returns (bytes32) {} + + function cumulativeWithdrawalsQueued( + address staker + ) external view returns (uint256) {} + + function calculateWithdrawalRoot( + Withdrawal memory withdrawal + ) external pure returns (bytes32) {} + + function operatorSaltIsSpent( + address avs, + bytes32 salt + ) external view returns (bool) {} + + function queueWithdrawals( + QueuedWithdrawalParams[] calldata queuedWithdrawalParams + ) external returns (bytes32[] memory) {} + + function completeQueuedWithdrawal( + Withdrawal calldata withdrawal, + IERC20[] calldata tokens, + uint256 middlewareTimesIndex, + bool receiveAsTokens + ) external {} + + function completeQueuedWithdrawals( + Withdrawal[] calldata withdrawals, + IERC20[][] calldata tokens, + uint256[] calldata middlewareTimesIndexes, + bool[] calldata receiveAsTokens + ) external {} + + // onlyDelegationManager functions in StrategyManager + function addShares( + IStrategyManager strategyManager, + address staker, + IERC20 token, + IStrategy strategy, + uint256 shares + ) external { + strategyManager.addShares(staker, strategy, token, shares); + } + + function removeShares( + IStrategyManager strategyManager, + address staker, + IStrategy strategy, + uint256 shares + ) external { + strategyManager.removeDepositShares(staker, strategy, shares); + } + + function withdrawSharesAsTokens( + IStrategyManager strategyManager, + address recipient, + IStrategy strategy, + uint256 shares, + IERC20 token + ) external { + strategyManager.withdrawSharesAsTokens(recipient, strategy, token, shares); + } + + function registerAsOperator( + OperatorDetails calldata registeringOperatorDetails, + uint32 allocationDelay, + string calldata metadataURI + ) external override {} + + function completeQueuedWithdrawal( + Withdrawal calldata withdrawal, + IERC20[] calldata tokens, + bool receiveAsTokens + ) external override {} + + function completeQueuedWithdrawals( + Withdrawal[] calldata withdrawals, + IERC20[][] calldata tokens, + bool[] calldata receiveAsTokens + ) external override {} + + function decreaseBeaconChainScalingFactor( + address staker, + uint256 existingDepositShares, + uint64 proportionOfOldBalance + ) external override {} + + function decreaseOperatorShares( + address operator, + IStrategy strategy, + uint64 previousTotalMagnitude, + uint64 newTotalMagnitude + ) external override {} + + function increaseDelegatedShares( + address staker, + IStrategy strategy, + uint256 existingDepositShares, + uint256 addedShares + ) external override {} + + function initialize( + address initialOwner, + IPauserRegistry _pauserRegistry, + uint256 initialPausedStatus + ) external override {} + + function getOperatorsShares( + address[] memory operators, + IStrategy[] memory strategies + ) external view override returns (uint256[][] memory) {} + + function getWithdrawableShares( + address staker, + IStrategy[] memory strategies + ) external view override returns (uint256[] memory withdrawableShares) {} + + function getDepositedShares( + address staker + ) external view override returns (IStrategy[] memory, uint256[] memory) {} + + function getCompletableTimestamp( + uint32 startTimestamp + ) external view override returns (uint32 completableTimestamp) {} } diff --git a/test/mocks/ECDSAServiceManagerMock.sol b/test/mocks/ECDSAServiceManagerMock.sol index 88e3ac6f..5be1d82d 100644 --- a/test/mocks/ECDSAServiceManagerMock.sol +++ b/test/mocks/ECDSAServiceManagerMock.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.12; import "../../src/unaudited/ECDSAServiceManagerBase.sol"; +import {IAllocationManagerTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol"; contract ECDSAServiceManagerMock is ECDSAServiceManagerBase { constructor( @@ -34,4 +35,8 @@ contract ECDSAServiceManagerMock is ECDSAServiceManagerBase { ) external {} function deregisterOperatorFromOperatorSets(address operator, uint32[] calldata operatorSetIds) external{} + + function slashOperator(IAllocationManagerTypes.SlashingParams memory params) external override { + // Mock implementation - no actual slashing occurs + } } diff --git a/test/mocks/EigenPodManagerMock.sol b/test/mocks/EigenPodManagerMock.sol new file mode 100644 index 00000000..afdd6189 --- /dev/null +++ b/test/mocks/EigenPodManagerMock.sol @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.9; + +import "forge-std/Test.sol"; +import "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IEigenPodManager.sol"; + +contract EigenPodManagerMock is Test, Pausable, IEigenPodManager { + receive() external payable {} + fallback() external payable {} + + mapping(address => int256) public podShares; + + constructor(IPauserRegistry _pauserRegistry) { + _initializePauser(_pauserRegistry, 0); + } + + function podOwnerShares(address podOwner) external view returns (int256) { + return podShares[podOwner]; + } + + function setPodOwnerShares(address podOwner, int256 shares) external { + podShares[podOwner] = shares; + } + + function denebForkTimestamp() external pure returns (uint64) { + return type(uint64).max; + } + + function createPod() external returns (address) { + } + + function stake(bytes calldata pubkey, bytes calldata signature, bytes32 depositDataRoot) external payable { + } + + function recordBeaconChainETHBalanceUpdate( + address podOwner, + int256 sharesDelta, + uint64 proportionPodBalanceDecrease + ) external { + } + + function ownerToPod(address podOwner) external view returns (IEigenPod) { + } + + function getPod(address podOwner) external view returns (IEigenPod) { + } + + function ethPOS() external view returns (IETHPOSDeposit) { + } + + function eigenPodBeacon() external view returns (IBeacon) { + } + + function strategyManager() external view returns (IStrategyManager) { + } + + function hasPod(address podOwner) external view returns (bool) { + } + + function numPods() external view returns (uint256) { + } + + function podOwnerDepositShares(address podOwner) external view returns (int256) { + } + + function beaconChainETHStrategy() external view returns (IStrategy) { + } + + function addShares(address staker, IStrategy strategy, IERC20 token, uint256 shares) external { + } + + function removeDepositShares(address staker, IStrategy strategy, uint256 depositSharesToRemove) external { + } + + function stakerDepositShares(address user, IStrategy strategy) external view returns (uint256 depositShares) { + } + + function withdrawSharesAsTokens(address staker, IStrategy strategy, IERC20 token, uint256 shares) external{} +} \ No newline at end of file diff --git a/test/mocks/RewardsCoordinatorMock.sol b/test/mocks/RewardsCoordinatorMock.sol index 2be3cd6c..cc8404a0 100644 --- a/test/mocks/RewardsCoordinatorMock.sol +++ b/test/mocks/RewardsCoordinatorMock.sol @@ -3,112 +3,131 @@ pragma solidity ^0.8.12; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; import {IRewardsCoordinator} from "eigenlayer-contracts/src/contracts/interfaces/IRewardsCoordinator.sol"; import "./AVSDirectoryMock.sol"; contract RewardsCoordinatorMock is IRewardsCoordinator { - /// @notice The address of the entity that can update the contract with new merkle roots - function rewardsUpdater() external view returns (address) {} + /// @notice The address of the entity that can update the contract with new merkle roots + function rewardsUpdater() external view returns (address) {} - function CALCULATION_INTERVAL_SECONDS() external view returns (uint32) {} + function CALCULATION_INTERVAL_SECONDS() external view returns (uint32) {} - function MAX_REWARDS_DURATION() external view returns (uint32) {} + function MAX_REWARDS_DURATION() external view returns (uint32) {} - function MAX_RETROACTIVE_LENGTH() external view returns (uint32) {} + function MAX_RETROACTIVE_LENGTH() external view returns (uint32) {} - function MAX_FUTURE_LENGTH() external view returns (uint32) {} + function MAX_FUTURE_LENGTH() external view returns (uint32) {} - function GENESIS_REWARDS_TIMESTAMP() external view returns (uint32) {} + function GENESIS_REWARDS_TIMESTAMP() external view returns (uint32) {} - function activationDelay() external view returns (uint32) {} + function activationDelay() external view returns (uint32) {} - function claimerFor(address earner) external view returns (address) {} + function claimerFor(address earner) external view returns (address) {} - function cumulativeClaimed(address claimer, IERC20 token) external view returns (uint256) {} + function cumulativeClaimed( + address claimer, + IERC20 token + ) external view returns (uint256) {} - /// @notice the commission for a specific operator for a specific avs - /// NOTE: Currently unused and simply returns the globalOperatorCommissionBips value but will be used in future release - function getOperatorCommissionBips( - address operator, - IAVSDirectory.OperatorSet calldata operatorSet, - RewardType rewardType - ) external view returns (uint16) {} + function globalOperatorCommissionBips() external view returns (uint16) {} - /// @notice returns the length of the operator commission update history - function getOperatorCommissionUpdateHistoryLength( - address operator, - IAVSDirectory.OperatorSet calldata operatorSet, - RewardType rewardType - ) external view returns (uint256) {} + function operatorCommissionBips( + address operator, + address avs + ) external view returns (uint16) {} - function globalOperatorCommissionBips() external view returns (uint16) {} + function calculateEarnerLeafHash( + EarnerTreeMerkleLeaf calldata leaf + ) external pure returns (bytes32) {} - function operatorCommissionBips(address operator, address avs) external view returns (uint16) {} + function calculateTokenLeafHash( + TokenTreeMerkleLeaf calldata leaf + ) external pure returns (bytes32) {} - function calculateEarnerLeafHash(EarnerTreeMerkleLeaf calldata leaf) external pure returns (bytes32) {} + function checkClaim( + RewardsMerkleClaim calldata claim + ) external view returns (bool) {} - function calculateTokenLeafHash(TokenTreeMerkleLeaf calldata leaf) external pure returns (bytes32) {} + function currRewardsCalculationEndTimestamp() + external + view + returns (uint32) + {} - function checkClaim(RewardsMerkleClaim calldata claim) external view returns (bool) {} + function getRootIndexFromHash( + bytes32 rootHash + ) external view returns (uint32) {} - function currRewardsCalculationEndTimestamp() external view returns (uint32) {} + function getDistributionRootsLength() external view returns (uint256) {} - function getRootIndexFromHash(bytes32 rootHash) external view returns (uint32) {} + function getDistributionRootAtIndex( + uint256 index + ) external view returns (DistributionRoot memory) {} - function getDistributionRootsLength() external view returns (uint256) {} + function getCurrentClaimableDistributionRoot() + external + view + returns (DistributionRoot memory) + {} - function getDistributionRootAtIndex(uint256 index) external view returns (DistributionRoot memory) {} + function getCurrentDistributionRoot() + external + view + returns (DistributionRoot memory) + {} - function getCurrentClaimableDistributionRoot() external view returns (DistributionRoot memory) {} + /// EXTERNAL FUNCTIONS /// - function getCurrentDistributionRoot() external view returns (DistributionRoot memory) {} + function disableRoot(uint32 rootIndex) external {} - /// EXTERNAL FUNCTIONS /// + function createAVSRewardsSubmission( + RewardsSubmission[] calldata rewardsSubmissions + ) external {} - function disableRoot(uint32 rootIndex) external {} + function createRewardsForAllSubmission( + RewardsSubmission[] calldata rewardsSubmission + ) external {} - function createAVSRewardsSubmission(RewardsSubmission[] calldata rewardsSubmissions) external {} + function processClaim( + RewardsMerkleClaim calldata claim, + address recipient + ) external {} - function createRewardsForAllSubmission(RewardsSubmission[] calldata rewardsSubmission) external {} + function submitRoot( + bytes32 root, + uint32 rewardsCalculationEndTimestamp + ) external {} - function processClaim(RewardsMerkleClaim calldata claim, address recipient) external {} + function setRewardsUpdater(address _rewardsUpdater) external {} - function submitRoot( - bytes32 root, - uint32 rewardsCalculationEndTimestamp - ) external {} + function setActivationDelay(uint32 _activationDelay) external {} - function setRewardsUpdater(address _rewardsUpdater) external {} + function setGlobalOperatorCommission(uint16 _globalCommissionBips) external {} - function setActivationDelay(uint32 _activationDelay) external {} + function setClaimerFor(address claimer) external {} - function setGlobalOperatorCommission(uint16 _globalCommissionBips) external {} + /** + * @notice Sets the permissioned `payAllForRangeSubmitter` address which can submit payAllForRange + * @dev Only callable by the contract owner + * @param _submitter The address of the payAllForRangeSubmitter + * @param _newValue The new value for isPayAllForRangeSubmitter + */ + function setRewardsForAllSubmitter( + address _submitter, + bool _newValue + ) external {} - function setClaimerFor(address claimer) external {} - - /** - * @notice Sets the permissioned `payAllForRangeSubmitter` address which can submit payAllForRange - * @dev Only callable by the contract owner - * @param _submitter The address of the payAllForRangeSubmitter - * @param _newValue The new value for isPayAllForRangeSubmitter - */ - function setRewardsForAllSubmitter(address _submitter, bool _newValue) external {} - - /** - * @notice Sets the commission an operator takes in bips for a given reward type and operatorSet - * @param operatorSet The operatorSet to update commission for - * @param rewardType The associated rewardType to update commission for - * @param commissionBips The commission in bips for the operator, must be <= MAX_COMMISSION_BIPS - * @return effectTimestamp The timestamp at which the operator commission update will take effect - * - * @dev The commission can range from 1 to 10000 - * @dev The commission update takes effect after 7 days - */ - function setOperatorCommissionBips( - IAVSDirectory.OperatorSet calldata operatorSet, - RewardType rewardType, - uint16 commissionBips - ) external returns (uint32) {} - - function rewardOperatorSetForRange(OperatorSetRewardsSubmission[] calldata rewardsSubmissions) external{} + function createRewardsForAllEarners( + RewardsSubmission[] calldata rewardsSubmissions + ) external override {} + + function initialize( + address initialOwner, + IPauserRegistry _pauserRegistry, + uint256 initialPausedStatus, + address _rewardsUpdater, + uint32 _activationDelay, + uint16 _globalCommissionBips + ) external override {} } \ No newline at end of file diff --git a/test/mocks/ServiceManagerMock.sol b/test/mocks/ServiceManagerMock.sol index 8af99426..a9bb5fff 100644 --- a/test/mocks/ServiceManagerMock.sol +++ b/test/mocks/ServiceManagerMock.sol @@ -8,15 +8,23 @@ contract ServiceManagerMock is ServiceManagerBase { IAVSDirectory _avsDirectory, IRewardsCoordinator _rewardsCoordinator, IRegistryCoordinator _registryCoordinator, - IStakeRegistry _stakeRegistry + IStakeRegistry _stakeRegistry, + IAllocationManager _allocationManager ) - ServiceManagerBase(_avsDirectory, _rewardsCoordinator, _registryCoordinator, _stakeRegistry) + ServiceManagerBase( + _avsDirectory, + _rewardsCoordinator, + _registryCoordinator, + _stakeRegistry, + _allocationManager + ) {} function initialize( address initialOwner, - address rewardsInitiator + address rewardsInitiator, + address slasher ) public virtual initializer { - __ServiceManagerBase_init(initialOwner, rewardsInitiator); + __ServiceManagerBase_init(initialOwner, rewardsInitiator, slasher); } } diff --git a/test/unit/ECDSAServiceManager.t.sol b/test/unit/ECDSAServiceManager.t.sol index 3b533d47..1093b77a 100644 --- a/test/unit/ECDSAServiceManager.t.sol +++ b/test/unit/ECDSAServiceManager.t.sol @@ -145,14 +145,15 @@ contract ECDSAServiceManagerSetup is Test { shares[0] = 0; shares[1] = 1; - vm.mockCall( - address(mockDelegationManager), - abi.encodeCall( - IDelegationManager.getOperatorShares, - (operator, strategies) - ), - abi.encode(shares) - ); + // TODO: Fix + // vm.mockCall( + // address(mockDelegationManager), + // abi.encodeCall( + // IDelegationManager.getOperatorShares, + // (operator, strategies) + // ), + // abi.encode(shares) + // ); address[] memory restakedStrategies = serviceManager .getOperatorRestakedStrategies(operator); diff --git a/test/unit/RegistryCoordinatorMigration.t.sol b/test/unit/RegistryCoordinatorMigration.t.sol index 99fd38f4..63e4c837 100644 --- a/test/unit/RegistryCoordinatorMigration.t.sol +++ b/test/unit/RegistryCoordinatorMigration.t.sol @@ -5,12 +5,16 @@ import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import { RewardsCoordinator, IRewardsCoordinator, + IRewardsCoordinatorTypes, IERC20 } from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; import {IServiceManagerBaseEvents} from "../events/IServiceManagerBaseEvents.sol"; +import {IAVSDirectoryTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {AVSDirectoryHarness} from "../harnesses/AVSDirectoryHarness.sol"; +import {OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import "../utils/MockAVSDeployer.sol"; @@ -55,7 +59,8 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas avsDirectory, IRewardsCoordinator(address(rewardsCoordinatorMock)), registryCoordinator, - stakeRegistry + stakeRegistry, + allocationManager ); avsDirectoryHarness = new AVSDirectoryHarness(delegationMock); @@ -63,7 +68,8 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas avsDirectory, rewardsCoordinatorMock, registryCoordinator, - stakeRegistry + stakeRegistry, + allocationManager ); /// Needed to upgrade to a service manager that points to an AVS Directory that can track state vm.prank(proxyAdmin.owner()); @@ -90,7 +96,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas IERC20 token3 = new ERC20PresetFixedSupply( "pepe wif avs", "MOCK3", mockTokenInitialSupply, address(this) ); - strategyImplementation = new StrategyBase(strategyManagerMock); + strategyImplementation = new StrategyBase(IStrategyManager(address(strategyManagerMock))); strategyMock1 = StrategyBase( address( new TransparentUpgradeableProxy( @@ -129,13 +135,13 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas strategyManagerMock.setStrategyWhitelist(strategies[2], true); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) ); } @@ -226,7 +232,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas AVSDirectoryHarness(address(avsDirectory)).setAvsOperatorStatus( address(serviceManager), operatorAddress, - IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED + IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED ); } } @@ -263,7 +269,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas }) ); // sanity check if the operator was unregistered from the intended operator set - bool operatorIsUnRegistered = !avsDirectory.isMember(operators[0], IAVSDirectory.OperatorSet({ + bool operatorIsUnRegistered = !avsDirectory.isMember(operators[0], OperatorSet({ avs: address(serviceManager), operatorSetId: defaultQuorumNumber })); @@ -311,7 +317,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas AVSDirectoryHarness(address(avsDirectory)).setAvsOperatorStatus( address(serviceManager), operatorAddress, - IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED + IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED ); } } @@ -337,7 +343,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas address operatorToDeregister = operators[0]; - bool isOperatorRegistered = avsDirectory.isMember(operatorToDeregister, IAVSDirectory.OperatorSet({ + bool isOperatorRegistered = avsDirectory.isMember(operatorToDeregister, OperatorSet({ avs: address(serviceManager), operatorSetId: defaultQuorumNumber })); @@ -352,7 +358,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas registryCoordinator.deregisterOperator(quorumNumbers); cheats.stopPrank(); - isOperatorRegistered = avsDirectory.isMember(operatorToDeregister, IAVSDirectory.OperatorSet({ + isOperatorRegistered = avsDirectory.isMember(operatorToDeregister, OperatorSet({ avs: address(serviceManager), operatorSetId: defaultQuorumNumber })); @@ -386,7 +392,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas AVSDirectoryHarness(address(avsDirectory)).setAvsOperatorStatus( address(serviceManager), operatorAddress, - IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED + IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED ); } } @@ -413,7 +419,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas uint256 operatorPk = uint256(keccak256("operator to register")); address operatorToRegister = vm.addr(operatorPk) ; - bool isOperatorRegistered = avsDirectory.isMember(operatorToRegister, IAVSDirectory.OperatorSet({ + bool isOperatorRegistered = avsDirectory.isMember(operatorToRegister, OperatorSet({ avs: address(serviceManager), operatorSetId: defaultQuorumNumber })); @@ -453,7 +459,7 @@ contract RegistryCoordinatorMigrationUnit is MockAVSDeployer, IServiceManagerBas registryCoordinator.registerOperator(quorumNumbers, "", params, operatorSignature); cheats.stopPrank(); - isOperatorRegistered = avsDirectory.isMember(operatorToRegister, IAVSDirectory.OperatorSet({ + isOperatorRegistered = avsDirectory.isMember(operatorToRegister, OperatorSet({ avs: address(serviceManager), operatorSetId: defaultQuorumNumber })); diff --git a/test/unit/ServiceManagerBase.t.sol b/test/unit/ServiceManagerBase.t.sol index eba791c3..1d333814 100644 --- a/test/unit/ServiceManagerBase.t.sol +++ b/test/unit/ServiceManagerBase.t.sol @@ -5,9 +5,11 @@ import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import { RewardsCoordinator, IRewardsCoordinator, + IRewardsCoordinatorTypes, IERC20 } from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {IServiceManagerBaseEvents} from "../events/IServiceManagerBaseEvents.sol"; import "../utils/MockAVSDeployer.sol"; @@ -53,15 +55,12 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve // Deploy rewards coordinator rewardsCoordinatorImplementation = new RewardsCoordinator( delegationMock, - strategyManagerMock, - avsDirectoryMock, + IStrategyManager(address(strategyManagerMock)), CALCULATION_INTERVAL_SECONDS, MAX_REWARDS_DURATION, MAX_RETROACTIVE_LENGTH, MAX_FUTURE_LENGTH, - GENESIS_REWARDS_TIMESTAMP, - OPERATOR_SET_GENESIS_REWARDS_TIMESTAMP, - OPERATOR_SET_MAX_RETROACTIVE_LENGTH + GENESIS_REWARDS_TIMESTAMP ); rewardsCoordinator = RewardsCoordinator( @@ -86,7 +85,8 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve avsDirectory, rewardsCoordinator, registryCoordinatorImplementation, - stakeRegistryImplementation + stakeRegistryImplementation, + allocationManagerImplementation ); serviceManager = ServiceManagerMock( @@ -146,7 +146,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve IERC20 token3 = new ERC20PresetFixedSupply( "pepe wif avs", "MOCK3", mockTokenInitialSupply, address(this) ); - strategyImplementation = new StrategyBase(strategyManagerMock); + strategyImplementation = new StrategyBase(IStrategyManager(address(strategyManagerMock))); strategyMock1 = StrategyBase( address( new TransparentUpgradeableProxy( @@ -185,13 +185,13 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve strategyManagerMock.setStrategyWhitelist(strategies[2], true); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) ); } @@ -233,9 +233,9 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve "dog wif hat", "MOCK1", mockTokenInitialSupply, rewardsInitiator ); - IRewardsCoordinator.RewardsSubmission[] memory rewardsSubmissions = - new IRewardsCoordinator.RewardsSubmission[](1); - rewardsSubmissions[0] = IRewardsCoordinator.RewardsSubmission({ + IRewardsCoordinatorTypes.RewardsSubmission[] memory rewardsSubmissions = + new IRewardsCoordinatorTypes.RewardsSubmission[](1); + rewardsSubmissions[0] = IRewardsCoordinatorTypes.RewardsSubmission({ strategiesAndMultipliers: defaultStrategyAndMultipliers, token: token, amount: 100, @@ -272,9 +272,9 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve startTimestamp = startTimestamp - (startTimestamp % CALCULATION_INTERVAL_SECONDS); // 2. Create reward submission input param - IRewardsCoordinator.RewardsSubmission[] memory rewardsSubmissions = - new IRewardsCoordinator.RewardsSubmission[](1); - rewardsSubmissions[0] = IRewardsCoordinator.RewardsSubmission({ + IRewardsCoordinatorTypes.RewardsSubmission[] memory rewardsSubmissions = + new IRewardsCoordinatorTypes.RewardsSubmission[](1); + rewardsSubmissions[0] = IRewardsCoordinatorTypes.RewardsSubmission({ strategiesAndMultipliers: defaultStrategyAndMultipliers, token: rewardToken, amount: amount, @@ -365,7 +365,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve startTimestamp = startTimestamp - (startTimestamp % CALCULATION_INTERVAL_SECONDS); // 2. Create reward submission input param - IRewardsCoordinator.RewardsSubmission memory rewardsSubmission = IRewardsCoordinator.RewardsSubmission({ + IRewardsCoordinatorTypes.RewardsSubmission memory rewardsSubmission = IRewardsCoordinatorTypes.RewardsSubmission({ strategiesAndMultipliers: defaultStrategyAndMultipliers, token: rewardTokens[i], amount: amounts[i], @@ -463,7 +463,7 @@ contract ServiceManagerBase_UnitTests is MockAVSDeployer, IServiceManagerBaseEve startTimestamp = startTimestamp - (startTimestamp % CALCULATION_INTERVAL_SECONDS); // 2. Create reward submission input param - IRewardsCoordinator.RewardsSubmission memory rewardsSubmission = IRewardsCoordinator.RewardsSubmission({ + IRewardsCoordinatorTypes.RewardsSubmission memory rewardsSubmission = IRewardsCoordinatorTypes.RewardsSubmission({ strategiesAndMultipliers: defaultStrategyAndMultipliers, token: rewardToken, amount: amounts[i], diff --git a/test/unit/ServiceManagerMigration.t.sol b/test/unit/ServiceManagerMigration.t.sol index 69cd4c7c..67350529 100644 --- a/test/unit/ServiceManagerMigration.t.sol +++ b/test/unit/ServiceManagerMigration.t.sol @@ -5,11 +5,15 @@ import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import { RewardsCoordinator, IRewardsCoordinator, + IRewardsCoordinatorTypes, IERC20 } from "eigenlayer-contracts/src/contracts/core/RewardsCoordinator.sol"; import {StrategyBase} from "eigenlayer-contracts/src/contracts/strategies/StrategyBase.sol"; import {IServiceManagerBaseEvents} from "../events/IServiceManagerBaseEvents.sol"; +import {IAVSDirectoryTypes} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; +import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; import {AVSDirectoryHarness} from "../harnesses/AVSDirectoryHarness.sol"; +import {OperatorSet} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; import "../utils/MockAVSDeployer.sol"; @@ -59,15 +63,12 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa // Deploy rewards coordinator rewardsCoordinatorImplementation = new RewardsCoordinator( delegationMock, - strategyManagerMock, - avsDirectoryMock, + IStrategyManager(address(strategyManagerMock)), CALCULATION_INTERVAL_SECONDS, MAX_REWARDS_DURATION, MAX_RETROACTIVE_LENGTH, MAX_FUTURE_LENGTH, - GENESIS_REWARDS_TIMESTAMP, - OPERATOR_SET_GENESIS_REWARDS_TIMESTAMP, - OPERATOR_SET_MAX_RETROACTIVE_LENGTH + GENESIS_REWARDS_TIMESTAMP ); rewardsCoordinator = RewardsCoordinator( @@ -89,7 +90,7 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa ); // Deploy ServiceManager serviceManagerImplementation = new ServiceManagerMock( - avsDirectory, rewardsCoordinator, registryCoordinator, stakeRegistry + avsDirectory, rewardsCoordinator, registryCoordinator, stakeRegistry, allocationManager ); serviceManager = ServiceManagerMock( @@ -126,7 +127,7 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa IERC20 token3 = new ERC20PresetFixedSupply( "pepe wif avs", "MOCK3", mockTokenInitialSupply, address(this) ); - strategyImplementation = new StrategyBase(strategyManagerMock); + strategyImplementation = new StrategyBase(IStrategyManager(address(strategyManagerMock))); strategyMock1 = StrategyBase( address( new TransparentUpgradeableProxy( @@ -165,13 +166,13 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa strategyManagerMock.setStrategyWhitelist(strategies[2], true); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[0])), 1e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[1])), 2e18) ); defaultStrategyAndMultipliers.push( - IRewardsCoordinator.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) + IRewardsCoordinatorTypes.StrategyAndMultiplier(IStrategy(address(strategies[2])), 3e18) ); } @@ -320,7 +321,7 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa AVSDirectoryHarness(address(avsDirectory)).setAvsOperatorStatus( address(serviceManager), operatorAddress, - IAVSDirectory.OperatorAVSRegistrationStatus.REGISTERED + IAVSDirectoryTypes.OperatorAVSRegistrationStatus.REGISTERED ); } } @@ -339,7 +340,7 @@ contract ServiceManagerMigration_UnitTests is MockAVSDeployer, IServiceManagerBa assertTrue( avsDirectory.isMember( 0x73e2Ce949f15Be901f76b54F5a4554A6C8DCf539, - IAVSDirectory.OperatorSet(address(serviceManager), uint32(3)) + OperatorSet(address(serviceManager), uint32(3)) ), "Operator not migrated to operator set" ); diff --git a/test/unit/ServiceManagerRouter.t.sol b/test/unit/ServiceManagerRouter.t.sol index 9fc2c0f7..6706ade4 100644 --- a/test/unit/ServiceManagerRouter.t.sol +++ b/test/unit/ServiceManagerRouter.t.sol @@ -19,7 +19,8 @@ contract ServiceManagerRouter_UnitTests is MockAVSDeployer { avsDirectory, rewardsCoordinatorImplementation, registryCoordinatorImplementation, - stakeRegistryImplementation + stakeRegistryImplementation, + allocationManagerImplementation ); _registerOperatorWithCoordinator(defaultOperator, MAX_QUORUM_BITMAP, defaultPubKey); diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index b06364a8..af8ebe78 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -4,8 +4,6 @@ pragma solidity ^0.8.12; import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import {Slasher} from "eigenlayer-contracts/src/contracts/core/Slasher.sol"; -import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; import {PauserRegistry} from "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; import {ISignatureUtils} from "eigenlayer-contracts/src/contracts/interfaces/ISignatureUtils.sol"; @@ -26,8 +24,9 @@ import {IRegistryCoordinator} from "../../src/interfaces/IRegistryCoordinator.so import {IServiceManager} from "../../src/interfaces/IServiceManager.sol"; import {StrategyManagerMock} from "eigenlayer-contracts/src/test/mocks/StrategyManagerMock.sol"; -import {EigenPodManagerMock} from "eigenlayer-contracts/src/test/mocks/EigenPodManagerMock.sol"; +import {EigenPodManagerMock} from "../mocks/EigenPodManagerMock.sol"; import {AVSDirectoryMock} from "../mocks/AVSDirectoryMock.sol"; +import {AllocationManagerMock} from "../mocks/AllocationManagerMock.sol"; import {DelegationMock} from "../mocks/DelegationMock.sol"; import {AVSDirectory} from "eigenlayer-contracts/src/contracts/core/AVSDirectory.sol"; import {IAVSDirectory} from "eigenlayer-contracts/src/contracts/interfaces/IAVSDirectory.sol"; @@ -53,9 +52,6 @@ contract MockAVSDeployer is Test { ProxyAdmin public proxyAdmin; PauserRegistry public pauserRegistry; - ISlasher public slasher = ISlasher(address(uint160(uint256(keccak256("slasher"))))); - Slasher public slasherImplementation; - EmptyContract public emptyContract; RegistryCoordinatorHarness public registryCoordinatorImplementation; @@ -63,6 +59,7 @@ contract MockAVSDeployer is Test { IBLSApkRegistry public blsApkRegistryImplementation; IIndexRegistry public indexRegistryImplementation; ServiceManagerMock public serviceManagerImplementation; + AllocationManagerMock public allocationManagerImplementation; OperatorStateRetriever public operatorStateRetriever; RegistryCoordinatorHarness public registryCoordinator; @@ -70,6 +67,7 @@ contract MockAVSDeployer is Test { BLSApkRegistryHarness public blsApkRegistry; IIndexRegistry public indexRegistry; ServiceManagerMock public serviceManager; + AllocationManagerMock public allocationManager; StrategyManagerMock public strategyManagerMock; DelegationMock public delegationMock; @@ -77,6 +75,7 @@ contract MockAVSDeployer is Test { AVSDirectory public avsDirectory; AVSDirectory public avsDirectoryImplementation; AVSDirectoryMock public avsDirectoryMock; + AllocationManagerMock public allocationManagerMock; RewardsCoordinator public rewardsCoordinator; RewardsCoordinator public rewardsCoordinatorImplementation; RewardsCoordinatorMock public rewardsCoordinatorMock; @@ -150,23 +149,10 @@ contract MockAVSDeployer is Test { avsDirectoryMock = new AVSDirectoryMock(); eigenPodManagerMock = new EigenPodManagerMock(pauserRegistry); strategyManagerMock = new StrategyManagerMock(); - slasherImplementation = new Slasher(strategyManagerMock, delegationMock); - slasher = Slasher( - address( - new TransparentUpgradeableProxy( - address(slasherImplementation), - address(proxyAdmin), - abi.encodeWithSelector( - Slasher.initialize.selector, - msg.sender, - pauserRegistry, - 0 /*initialPausedStatus*/ - ) - ) - ) - ); + allocationManagerMock = new AllocationManagerMock(); avsDirectoryMock = new AVSDirectoryMock(); - avsDirectoryImplementation = new AVSDirectory(delegationMock); + allocationManagerMock = new AllocationManagerMock(); + avsDirectoryImplementation = new AVSDirectory(delegationMock, 0); // TODO: config value avsDirectory = AVSDirectory( address( new TransparentUpgradeableProxy( @@ -183,7 +169,7 @@ contract MockAVSDeployer is Test { ); rewardsCoordinatorMock = new RewardsCoordinatorMock(); - strategyManagerMock.setAddresses(delegationMock, eigenPodManagerMock, slasher); + strategyManagerMock.setDelegationManager(delegationMock); cheats.stopPrank(); cheats.startPrank(registryCoordinatorOwner); @@ -217,6 +203,12 @@ contract MockAVSDeployer is Test { ) ); + allocationManager = AllocationManagerMock( + address( + new TransparentUpgradeableProxy(address(emptyContract), address(proxyAdmin), "") + ) + ); + cheats.stopPrank(); cheats.startPrank(proxyAdminOwner); @@ -247,7 +239,8 @@ contract MockAVSDeployer is Test { avsDirectoryMock, IRewardsCoordinator(address(rewardsCoordinatorMock)), registryCoordinator, - stakeRegistry + stakeRegistry, + allocationManager ); proxyAdmin.upgrade( @@ -255,9 +248,17 @@ contract MockAVSDeployer is Test { address(serviceManagerImplementation) ); + allocationManagerImplementation = new AllocationManagerMock(); + + proxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(allocationManager))), + address(allocationManagerImplementation) + ); + serviceManager.initialize({ initialOwner: registryCoordinatorOwner, - rewardsInitiator: address(proxyAdminOwner) + rewardsInitiator: proxyAdminOwner, + slasher: proxyAdminOwner }); // set the public key for an operator, using harnessed function to bypass checks