From 89aff0069a2a6809bdb410578edd19e46a69a621 Mon Sep 17 00:00:00 2001 From: steven Date: Wed, 18 Oct 2023 09:46:17 -0400 Subject: [PATCH 1/6] add back scripts --- script/AVSContractsDeploy.s.sol | 769 ++++++++++++++++++++++++++++++ script/DeployOpenEigenLayer.s.sol | 204 ++++++++ 2 files changed, 973 insertions(+) create mode 100644 script/AVSContractsDeploy.s.sol create mode 100644 script/DeployOpenEigenLayer.s.sol diff --git a/script/AVSContractsDeploy.s.sol b/script/AVSContractsDeploy.s.sol new file mode 100644 index 00000000..304d1181 --- /dev/null +++ b/script/AVSContractsDeploy.s.sol @@ -0,0 +1,769 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity =0.8.12; + +import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; + +import "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IBeaconChainOracle.sol"; + +import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; +import "eigenlayer-contracts/src/contracts/core/Slasher.sol"; +import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; + +import "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; + +import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; +import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; +import "eigenlayer-contracts/src/contracts/pods/DelayedWithdrawalRouter.sol"; + +import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; +import "eigenlayer-contracts/src/contracts/middleware/BLSPublicKeyCompendium.sol"; + +import "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; +import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol"; +import "eigenlayer-contracts/src/test/mocks/ERC20Mock.sol"; + +import "forge-std/Script.sol"; +import "forge-std/Test.sol"; + +// # To load the variables in the .env file +// source .env + +// # To deploy and verify our contract +// forge script script/EigenLayerDeploy.s.sol --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv +contract EigenLayerDeploy is Script, Test { + Vm cheats = Vm(HEVM_ADDRESS); + + // struct used to encode token info in config file + struct StrategyConfig { + uint256 maxDeposits; + uint256 maxPerDeposit; + address tokenAddress; + string tokenSymbol; + } + + // EigenLayer Contracts + ProxyAdmin public eigenLayerProxyAdmin; + PauserRegistry public eigenLayerPauserReg; + Slasher public slasher; + Slasher public slasherImplementation; + DelegationManager public delegation; + DelegationManager public delegationImplementation; + StrategyManager public strategyManager; + StrategyManager public strategyManagerImplementation; + EigenPodManager public eigenPodManager; + EigenPodManager public eigenPodManagerImplementation; + DelayedWithdrawalRouter public delayedWithdrawalRouter; + DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; + UpgradeableBeacon public eigenPodBeacon; + EigenPod public eigenPodImplementation; + StrategyBase public ERC20MockStrategy; + StrategyBase public ERC20MockStrategyImplementation; + + EmptyContract public emptyContract; + + address alphaMultisig; + + // the ETH2 deposit contract -- if not on mainnet, we deploy a mock as stand-in + IETHPOSDeposit public ethPOSDeposit; + + // strategies deployed + + // IMMUTABLES TO SET + uint256 REQUIRED_BALANCE_WEI; + + // OTHER DEPLOYMENT PARAMETERS + uint256 STRATEGY_MANAGER_INIT_PAUSED_STATUS; + uint256 SLASHER_INIT_PAUSED_STATUS; + uint256 DELEGATION_INIT_PAUSED_STATUS; + uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS; + uint256 EIGENPOD_MANAGER_MAX_PODS; + uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS; + + // one week in blocks -- 50400 + uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS; + uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS; + string public deployConfigPath = string(bytes("script/configs/AVSContractsDeploy.json")); + + function run() external { + // read and log the chainID + uint256 chainId = block.chainid; + emit log_named_uint("You are deploying on ChainID", chainId); + + // READ JSON CONFIG DATA + string memory config_data = vm.readFile(deployConfigPath); + + STRATEGY_MANAGER_INIT_PAUSED_STATUS = stdJson.readUint( + config_data, + ".strategyManager.init_paused_status" + ); + SLASHER_INIT_PAUSED_STATUS = stdJson.readUint( + config_data, + ".slasher.init_paused_status" + ); + DELEGATION_INIT_PAUSED_STATUS = stdJson.readUint( + config_data, + ".delegation.init_paused_status" + ); + EIGENPOD_MANAGER_MAX_PODS = stdJson.readUint( + config_data, + ".eigenPodManager.max_pods" + ); + EIGENPOD_MANAGER_INIT_PAUSED_STATUS = stdJson.readUint( + config_data, + ".eigenPodManager.init_paused_status" + ); + DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = stdJson.readUint( + config_data, + ".delayedWithdrawalRouter.init_paused_status" + ); + + STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( + stdJson.readUint( + config_data, + ".strategyManager.init_withdrawal_delay_blocks" + ) + ); + DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = uint32( + stdJson.readUint( + config_data, + ".strategyManager.init_withdrawal_delay_blocks" + ) + ); + + REQUIRED_BALANCE_WEI = stdJson.readUint( + config_data, + ".eigenPod.REQUIRED_BALANCE_WEI" + ); + + + alphaMultisig = stdJson.readAddress( + config_data, + ".multisig_addresses.alphaMultisig" + ); + + require( + alphaMultisig != address(0), + "alphaMultisig address not configured correctly!" + ); + + // START RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.startBroadcast(); + + // deploy proxy admin for ability to upgrade proxy contracts + eigenLayerProxyAdmin = new ProxyAdmin(); + + //deploy pauser registry + { + address[] memory pausers = new address[](1); + pausers[0] = alphaMultisig; + eigenLayerPauserReg = new PauserRegistry(pausers, alphaMultisig); + } + + /** + * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are + * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. + */ + emptyContract = new EmptyContract(); + delegation = DelegationManager( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(eigenLayerProxyAdmin), + "" + ) + ) + ); + strategyManager = StrategyManager( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(eigenLayerProxyAdmin), + "" + ) + ) + ); + slasher = Slasher( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(eigenLayerProxyAdmin), + "" + ) + ) + ); + eigenPodManager = EigenPodManager( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(eigenLayerProxyAdmin), + "" + ) + ) + ); + delayedWithdrawalRouter = DelayedWithdrawalRouter( + address( + new TransparentUpgradeableProxy( + address(emptyContract), + address(eigenLayerProxyAdmin), + "" + ) + ) + ); + + // if on mainnet, use the ETH2 deposit contract address + if (chainId == 1) { + ethPOSDeposit = IETHPOSDeposit( + 0x00000000219ab540356cBB839Cbe05303d7705Fa + ); + // if not on mainnet, deploy a mock + } else { + ethPOSDeposit = IETHPOSDeposit( + stdJson.readAddress(config_data, ".ethPOSDepositAddress") + ); + } + eigenPodImplementation = new EigenPod( + ethPOSDeposit, + delayedWithdrawalRouter, + eigenPodManager, + uint64(REQUIRED_BALANCE_WEI), + uint64(REQUIRED_BALANCE_WEI), + 1000 // temp genesis time, TODO: set if needed + ); + + eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); + + // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs + delegationImplementation = new DelegationManager( + strategyManager, + slasher, + eigenPodManager + ); + strategyManagerImplementation = new StrategyManager( + delegation, + eigenPodManager, + slasher + ); + slasherImplementation = new Slasher(strategyManager, delegation); + eigenPodManagerImplementation = new EigenPodManager( + ethPOSDeposit, + eigenPodBeacon, + strategyManager, + slasher, + delegation + ); + delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter( + eigenPodManager + ); + + // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(delegation))), + address(delegationImplementation), + abi.encodeWithSelector( + DelegationManager.initialize.selector, + alphaMultisig, + eigenLayerPauserReg, + DELEGATION_INIT_PAUSED_STATUS + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(strategyManager))), + address(strategyManagerImplementation), + abi.encodeWithSelector( + StrategyManager.initialize.selector, + alphaMultisig, + alphaMultisig, + eigenLayerPauserReg, + STRATEGY_MANAGER_INIT_PAUSED_STATUS, + STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(slasher))), + address(slasherImplementation), + abi.encodeWithSelector( + Slasher.initialize.selector, + alphaMultisig, + eigenLayerPauserReg, + SLASHER_INIT_PAUSED_STATUS + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation), + abi.encodeWithSelector( + EigenPodManager.initialize.selector, + EIGENPOD_MANAGER_MAX_PODS, + IBeaconChainOracle(address(0)), + alphaMultisig, + eigenLayerPauserReg, + EIGENPOD_MANAGER_INIT_PAUSED_STATUS + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy( + payable(address(delayedWithdrawalRouter)) + ), + address(delayedWithdrawalRouterImplementation), + abi.encodeWithSelector( + DelayedWithdrawalRouter.initialize.selector, + alphaMultisig, + eigenLayerPauserReg, + DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS, + DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS + ) + ); + + IERC20 mockToken = new ERC20Mock(); + + // ERC20MockStrategy = StrategyBase( + // address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + // ); + + // deploy StrategyBaseTVLLimits contract implementation + ERC20MockStrategyImplementation = new StrategyBase(strategyManager); + // create upgradeable proxies that each point to the implementation and initialize them + + // eigenLayerProxyAdmin.upgradeAndCall( + // TransparentUpgradeableProxy(payable(address(ERC20MockStrategy))), + // address(ERC20MockStrategyImplementation), + // abi.encodeWithSelector( + // EigenPodManager.initialize.selector, + // EIGENPOD_MANAGER_MAX_PODS, + // IBeaconChainOracle(address(0)), + // alphaMultisig, + // eigenLayerPauserReg, + // EIGENPOD_MANAGER_INIT_PAUSED_STATUS + // ) + // ); + + ERC20MockStrategy = StrategyBase( + address( + new TransparentUpgradeableProxy( + address(ERC20MockStrategyImplementation), + address(eigenLayerProxyAdmin), + abi.encodeWithSelector( + StrategyBase.initialize.selector, + mockToken, + eigenLayerPauserReg + ) + ) + ) + ); + + eigenLayerProxyAdmin.transferOwnership(alphaMultisig); + eigenPodBeacon.transferOwnership(alphaMultisig); + + // STOP RECORDING TRANSACTIONS FOR DEPLOYMENT + vm.stopBroadcast(); + + // CHECK CORRECTNESS OF DEPLOYMENT + _verifyContractsPointAtOneAnother( + delegationImplementation, + strategyManagerImplementation, + slasherImplementation, + eigenPodManagerImplementation, + delayedWithdrawalRouterImplementation + ); + _verifyContractsPointAtOneAnother( + delegation, + strategyManager, + slasher, + eigenPodManager, + delayedWithdrawalRouter + ); + _verifyImplementationsSetCorrectly(); + _verifyInitialOwners(); + _checkPauserInitializations(); + _verifyInitializationParams(); + + // WRITE JSON DATA + string memory parent_object = "parent object"; + + string memory deployed_addresses = "addresses"; + vm.serializeAddress( + deployed_addresses, + "eigenLayerProxyAdmin", + address(eigenLayerProxyAdmin) + ); + vm.serializeAddress( + deployed_addresses, + "eigenLayerPauserReg", + address(eigenLayerPauserReg) + ); + vm.serializeAddress(deployed_addresses, "slasher", address(slasher)); + vm.serializeAddress( + deployed_addresses, + "slasherImplementation", + address(slasherImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "delegation", + address(delegation) + ); + vm.serializeAddress( + deployed_addresses, + "delegationImplementation", + address(delegationImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "strategyManager", + address(strategyManager) + ); + vm.serializeAddress( + deployed_addresses, + "strategyManagerImplementation", + address(strategyManagerImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "eigenPodManager", + address(eigenPodManager) + ); + vm.serializeAddress( + deployed_addresses, + "eigenPodManagerImplementation", + address(eigenPodManagerImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "delayedWithdrawalRouter", + address(delayedWithdrawalRouter) + ); + vm.serializeAddress( + deployed_addresses, + "delayedWithdrawalRouterImplementation", + address(delayedWithdrawalRouterImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "eigenPodBeacon", + address(eigenPodBeacon) + ); + vm.serializeAddress( + deployed_addresses, + "eigenPodImplementation", + address(eigenPodImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "ERC20MockStrategy", + address(ERC20MockStrategy) + ); + vm.serializeAddress( + deployed_addresses, + "ERC20MockStrategyImplementation", + address(ERC20MockStrategyImplementation) + ); + vm.serializeAddress( + deployed_addresses, + "ERC20Mock", + address(mockToken) + ); + string memory deployed_addresses_output = vm.serializeAddress( + deployed_addresses, + "emptyContract", + address(emptyContract) + ); + + string memory parameters = "parameters"; + + string memory parameters_output = vm.serializeAddress( + parameters, + "alphaMultisig", + alphaMultisig + ); + + string memory chain_info = "chainInfo"; + vm.serializeUint(chain_info, "deploymentBlock", block.number); + string memory chain_info_output = vm.serializeUint( + chain_info, + "chainId", + chainId + ); + + // serialize all the data + vm.serializeString( + parent_object, + deployed_addresses, + deployed_addresses_output + ); + vm.serializeString( + parent_object, + chain_info, + chain_info_output + ); + string memory finalJson = vm.serializeString( + parent_object, + parameters, + parameters_output + ); + vm.writeJson(finalJson, "script/output/deployment_output.json"); + } + + function _verifyContractsPointAtOneAnother( + DelegationManager delegationContract, + StrategyManager strategyManagerContract, + Slasher slasherContract, + EigenPodManager eigenPodManagerContract, + DelayedWithdrawalRouter delayedWithdrawalRouterContract + ) internal view { + require( + delegationContract.slasher() == slasher, + "delegation: slasher address not set correctly" + ); + require( + delegationContract.strategyManager() == strategyManager, + "delegation: strategyManager address not set correctly" + ); + + require( + strategyManagerContract.slasher() == slasher, + "strategyManager: slasher address not set correctly" + ); + require( + strategyManagerContract.delegation() == delegation, + "strategyManager: delegation address not set correctly" + ); + require( + strategyManagerContract.eigenPodManager() == eigenPodManager, + "strategyManager: eigenPodManager address not set correctly" + ); + + require( + slasherContract.strategyManager() == strategyManager, + "slasher: strategyManager not set correctly" + ); + require( + slasherContract.delegation() == delegation, + "slasher: delegation not set correctly" + ); + + require( + eigenPodManagerContract.ethPOS() == ethPOSDeposit, + " eigenPodManager: ethPOSDeposit contract address not set correctly" + ); + require( + eigenPodManagerContract.eigenPodBeacon() == eigenPodBeacon, + "eigenPodManager: eigenPodBeacon contract address not set correctly" + ); + require( + eigenPodManagerContract.strategyManager() == strategyManager, + "eigenPodManager: strategyManager contract address not set correctly" + ); + require( + eigenPodManagerContract.slasher() == slasher, + "eigenPodManager: slasher contract address not set correctly" + ); + + require( + delayedWithdrawalRouterContract.eigenPodManager() == + eigenPodManager, + "delayedWithdrawalRouterContract: eigenPodManager address not set correctly" + ); + } + + function _verifyImplementationsSetCorrectly() internal view { + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(address(delegation))) + ) == address(delegationImplementation), + "delegation: implementation set incorrectly" + ); + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(address(strategyManager))) + ) == address(strategyManagerImplementation), + "strategyManager: implementation set incorrectly" + ); + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(address(slasher))) + ) == address(slasherImplementation), + "slasher: implementation set incorrectly" + ); + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(address(eigenPodManager))) + ) == address(eigenPodManagerImplementation), + "eigenPodManager: implementation set incorrectly" + ); + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy( + payable(address(delayedWithdrawalRouter)) + ) + ) == address(delayedWithdrawalRouterImplementation), + "delayedWithdrawalRouter: implementation set incorrectly" + ); + + require( + eigenLayerProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(address(ERC20MockStrategy))) + ) == address(ERC20MockStrategyImplementation), + "strategy: implementation set incorrectly" + ); + + require( + eigenPodBeacon.implementation() == address(eigenPodImplementation), + "eigenPodBeacon: implementation set incorrectly" + ); + } + + function _verifyInitialOwners() internal view { + require( + strategyManager.owner() == alphaMultisig, + "strategyManager: owner not set correctly" + ); + require( + delegation.owner() == alphaMultisig, + "delegation: owner not set correctly" + ); + require( + slasher.owner() == alphaMultisig, + "slasher: owner not set correctly" + ); + require( + eigenPodManager.owner() == alphaMultisig, + "delegation: owner not set correctly" + ); + + require( + eigenLayerProxyAdmin.owner() == alphaMultisig, + "eigenLayerProxyAdmin: owner not set correctly" + ); + require( + eigenPodBeacon.owner() == alphaMultisig, + "eigenPodBeacon: owner not set correctly" + ); + require( + delayedWithdrawalRouter.owner() == alphaMultisig, + "delayedWithdrawalRouter: owner not set correctly" + ); + } + + function _checkPauserInitializations() internal view { + require( + delegation.pauserRegistry() == eigenLayerPauserReg, + "delegation: pauser registry not set correctly" + ); + require( + strategyManager.pauserRegistry() == eigenLayerPauserReg, + "strategyManager: pauser registry not set correctly" + ); + require( + slasher.pauserRegistry() == eigenLayerPauserReg, + "slasher: pauser registry not set correctly" + ); + require( + eigenPodManager.pauserRegistry() == eigenLayerPauserReg, + "eigenPodManager: pauser registry not set correctly" + ); + require( + delayedWithdrawalRouter.pauserRegistry() == eigenLayerPauserReg, + "delayedWithdrawalRouter: pauser registry not set correctly" + ); + + require( + eigenLayerPauserReg.isPauser(alphaMultisig), + "pauserRegistry: alphaMultisig is not pauser" + ); + + require( + eigenLayerPauserReg.unpauser() == alphaMultisig, + "pauserRegistry: unpauser not set correctly" + ); + + require( + ERC20MockStrategy.pauserRegistry() == eigenLayerPauserReg, + "StrategyBaseTVLLimits: pauser registry not set correctly" + ); + require( + ERC20MockStrategy.paused() == 0, + "StrategyBaseTVLLimits: init paused status set incorrectly" + ); + + // // pause *nothing* + // uint256 STRATEGY_MANAGER_INIT_PAUSED_STATUS = 0; + // // pause *everything* + // uint256 SLASHER_INIT_PAUSED_STATUS = type(uint256).max; + // // pause *everything* + // uint256 DELEGATION_INIT_PAUSED_STATUS = type(uint256).max; + // // pause *all of the proof-related functionality* (everything that can be paused other than creation of EigenPods) + // uint256 EIGENPOD_MANAGER_INIT_PAUSED_STATUS = (2**1) + (2**2) + (2**3) + (2**4); /* = 30 */ + // // pause *nothing* + // uint256 DELAYED_WITHDRAWAL_ROUTER_INIT_PAUSED_STATUS = 0; + require( + strategyManager.paused() == 0, + "strategyManager: init paused status set incorrectly" + ); + require( + slasher.paused() == 0, + "slasher: init paused status set incorrectly" + ); + require( + delegation.paused() == 0, + "delegation: init paused status set incorrectly" + ); + require( + eigenPodManager.paused() == 30, + "eigenPodManager: init paused status set incorrectly" + ); + require( + delayedWithdrawalRouter.paused() == 0, + "delayedWithdrawalRouter: init paused status set incorrectly" + ); + } + + function _verifyInitializationParams() internal view { + // // one week in blocks -- 50400 + // uint32 STRATEGY_MANAGER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; + // uint32 DELAYED_WITHDRAWAL_ROUTER_INIT_WITHDRAWAL_DELAY_BLOCKS = 7 days / 12 seconds; + // require(strategyManager.withdrawalDelayBlocks() == 7 days / 12 seconds, + // "strategyManager: withdrawalDelayBlocks initialized incorrectly"); + // require(delayedWithdrawalRouter.withdrawalDelayBlocks() == 7 days / 12 seconds, + // "delayedWithdrawalRouter: withdrawalDelayBlocks initialized incorrectly"); + // uint256 REQUIRED_BALANCE_WEI = 31 ether; + + require( + strategyManager.strategyWhitelister() == alphaMultisig, + "strategyManager: strategyWhitelister address not set correctly" + ); + + require( + eigenPodManager.beaconChainOracle() == + IBeaconChainOracle(address(0)), + "eigenPodManager: eigenPodBeacon contract address not set correctly" + ); + + require( + delayedWithdrawalRouter.eigenPodManager() == eigenPodManager, + "delayedWithdrawalRouter: eigenPodManager set incorrectly" + ); + + require( + ERC20MockStrategyImplementation.strategyManager() == strategyManager, + "ERC20MockStrategyImplementation: strategyManager set incorrectly" + ); + + require( + eigenPodImplementation.ethPOS() == ethPOSDeposit, + "eigenPodImplementation: ethPOSDeposit contract address not set correctly" + ); + require( + eigenPodImplementation.eigenPodManager() == eigenPodManager, + " eigenPodImplementation: eigenPodManager contract address not set correctly" + ); + require( + eigenPodImplementation.delayedWithdrawalRouter() == + delayedWithdrawalRouter, + " eigenPodImplementation: delayedWithdrawalRouter contract address not set correctly" + ); + } +} diff --git a/script/DeployOpenEigenLayer.s.sol b/script/DeployOpenEigenLayer.s.sol new file mode 100644 index 00000000..0e852a88 --- /dev/null +++ b/script/DeployOpenEigenLayer.s.sol @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity =0.8.12; + +import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; +import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; + +import "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IBeaconChainOracle.sol"; + +import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; +import "eigenlayer-contracts/src/contracts/core/Slasher.sol"; +import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; + +import "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; + +import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; +import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; +import "eigenlayer-contracts/src/contracts/pods/DelayedWithdrawalRouter.sol"; + +import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; +import "src/BLSPublicKeyCompendium.sol"; + +import "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; +import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol"; + +import "forge-std/Script.sol"; +import "forge-std/Test.sol"; + +// # To load the variables in the .env file +// source .env + +// # To deploy and verify our contract +// forge script script/M1_Deploy.s.sol:Deployer_M1 --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv +contract DeployOpenEigenLayer is Script, Test { + Vm cheats = Vm(HEVM_ADDRESS); + + // struct used to encode token info in config file + struct StrategyConfig { + uint256 maxDeposits; + uint256 maxPerDeposit; + address tokenAddress; + string tokenSymbol; + } + + // EigenLayer Contracts + ProxyAdmin public eigenLayerProxyAdmin; + PauserRegistry public eigenLayerPauserReg; + Slasher public slasher; + Slasher public slasherImplementation; + DelegationManager public delegation; + DelegationManager public delegationImplementation; + StrategyManager public strategyManager; + StrategyManager public strategyManagerImplementation; + EigenPodManager public eigenPodManager; + EigenPodManager public eigenPodManagerImplementation; + DelayedWithdrawalRouter public delayedWithdrawalRouter; + DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; + UpgradeableBeacon public eigenPodBeacon; + EigenPod public eigenPodImplementation; + StrategyBase public baseStrategyImplementation; + + EmptyContract public emptyContract; + + // the ETH2 deposit contract -- if not on mainnet, we deploy a mock as stand-in + IETHPOSDeposit public ethPOSDeposit; + + // strategies deployed + StrategyBaseTVLLimits[] public deployedStrategyArray; + + function _deployEigenLayer(address executorMultisig, address operationsMultisig, address pauserMultisig, StrategyConfig[] memory strategyConfigs) internal { + require(executorMultisig != address(0), "executorMultisig address not configured correctly!"); + require(operationsMultisig != address(0), "operationsMultisig address not configured correctly!"); + + // deploy proxy admin for ability to upgrade proxy contracts + eigenLayerProxyAdmin = new ProxyAdmin(); + + //deploy pauser registry + { + address[] memory pausers = new address[](3); + pausers[0] = executorMultisig; + pausers[1] = operationsMultisig; + pausers[2] = pauserMultisig; + eigenLayerPauserReg = new PauserRegistry(pausers, executorMultisig); + } + + /** + * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are + * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. + */ + emptyContract = new EmptyContract(); + delegation = DelegationManager( + address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + ); + strategyManager = StrategyManager( + address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + ); + slasher = Slasher( + address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + ); + eigenPodManager = EigenPodManager( + address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + ); + delayedWithdrawalRouter = DelayedWithdrawalRouter( + address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) + ); + + // ETH POS deposit is 0 address + eigenPodImplementation = new EigenPod( + ethPOSDeposit, + delayedWithdrawalRouter, + eigenPodManager, + // uint64(MAX_VALIDATOR_BALANCE_GWEI), + uint64(31 gwei), + // uint64(EFFECTIVE_RESTAKED_BALANCE_OFFSET_GWEI) + uint64(0.75 gwei), + 1000 // temp genesis time + ); + + eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); + + // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs + delegationImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); + strategyManagerImplementation = new StrategyManager(delegation, eigenPodManager, slasher); + slasherImplementation = new Slasher(strategyManager, delegation); + eigenPodManagerImplementation = new EigenPodManager(ethPOSDeposit, eigenPodBeacon, strategyManager, slasher, delegation); + delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); + + // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(delegation))), + address(delegationImplementation), + abi.encodeWithSelector( + DelegationManager.initialize.selector, + executorMultisig, + eigenLayerPauserReg, + 0 + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(strategyManager))), + address(strategyManagerImplementation), + abi.encodeWithSelector( + StrategyManager.initialize.selector, + executorMultisig, + operationsMultisig, + eigenLayerPauserReg, + 0, + 0 + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(slasher))), + address(slasherImplementation), + abi.encodeWithSelector( + Slasher.initialize.selector, + executorMultisig, + eigenLayerPauserReg, + 0 + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(eigenPodManager))), + address(eigenPodManagerImplementation), + abi.encodeWithSelector( + EigenPodManager.initialize.selector, + type(uint256).max, + IBeaconChainOracle(address(0)), + executorMultisig, + eigenLayerPauserReg, + 0 + ) + ); + eigenLayerProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), + address(delayedWithdrawalRouterImplementation), + abi.encodeWithSelector(DelayedWithdrawalRouter.initialize.selector, + executorMultisig, + eigenLayerPauserReg, + 0, + 0 + ) + ); + + // deploy StrategyBaseTVLLimits contract implementation + baseStrategyImplementation = new StrategyBaseTVLLimits(strategyManager); + // create upgradeable proxies that each point to the implementation and initialize them + for (uint256 i = 0; i < strategyConfigs.length; ++i) { + deployedStrategyArray.push( + StrategyBaseTVLLimits(address( + new TransparentUpgradeableProxy( + address(baseStrategyImplementation), + address(eigenLayerProxyAdmin), + abi.encodeWithSelector(StrategyBaseTVLLimits.initialize.selector, strategyConfigs[i].maxPerDeposit, strategyConfigs[i].maxDeposits, IERC20(strategyConfigs[i].tokenAddress), eigenLayerPauserReg) + ) + )) + ); + } + + eigenLayerProxyAdmin.transferOwnership(executorMultisig); + eigenPodBeacon.transferOwnership(executorMultisig); + } +} From d571dd86b47ce2f96ba85468f88a91caed7f2b0a Mon Sep 17 00:00:00 2001 From: steven Date: Wed, 18 Oct 2023 15:45:54 -0400 Subject: [PATCH 2/6] add go operations --- foundry.toml | 2 ++ go.mod | 12 ++++++++++++ go.sum | 14 ++++++++++++++ test/ffi/util/G2Operations.sol | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/foundry.toml b/foundry.toml index 25b918f9..15ffb7fc 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,4 +3,6 @@ src = "src" out = "out" libs = ["lib"] +ffi = true + # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..e3390d9c --- /dev/null +++ b/go.mod @@ -0,0 +1,12 @@ +module github.com/Layr-Labs/ffi + +go 1.20 + +require ( + github.com/bits-and-blooms/bitset v1.5.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.11.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + golang.org/x/sys v0.2.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..0bc3f8d7 --- /dev/null +++ b/go.sum @@ -0,0 +1,14 @@ +github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.11.1 h1:pt2nLbntYZA5IXnSw21vcQgoUCRPn6J/xylWQpK8gtM= +github.com/consensys/gnark-crypto v0.11.1/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/test/ffi/util/G2Operations.sol b/test/ffi/util/G2Operations.sol index 9617f871..bc4d67d8 100644 --- a/test/ffi/util/G2Operations.sol +++ b/test/ffi/util/G2Operations.sol @@ -12,7 +12,7 @@ contract G2Operations is Test { string[] memory inputs = new string[](5); inputs[0] = "go"; inputs[1] = "run"; - inputs[2] = "src/test/ffi/go/g2mul.go"; + inputs[2] = "test/ffi/go/g2mul.go"; inputs[3] = x.toString(); inputs[4] = "1"; From cea4fc3d1aca80ff4b31553839efe47a5ba36f0f Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 20 Oct 2023 12:24:14 -0400 Subject: [PATCH 3/6] create interface shims --- src/BLSOperatorStateRetriever.sol | 10 +- src/BLSPubkeyRegistryStorage.sol | 8 +- src/BLSRegistryCoordinatorWithIndices.sol | 30 ++-- src/BLSSignatureChecker.sol | 14 +- src/ServiceManagerBase.sol | 16 +-- src/interfaces/IRegistry.sol | 13 +- src/interfaces/IRegistryCoordinator.sol | 95 +------------ src/interfaces/IServiceManager.sol | 37 +---- src/interfaces/IStakeRegistry.sol | 158 +--------------------- src/interfaces/IVoteWeigher.sol | 94 +------------ 10 files changed, 44 insertions(+), 431 deletions(-) diff --git a/src/BLSOperatorStateRetriever.sol b/src/BLSOperatorStateRetriever.sol index 3ed09104..85656e4c 100644 --- a/src/BLSOperatorStateRetriever.sol +++ b/src/BLSOperatorStateRetriever.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; -import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; -import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; -import {IIndexRegistry} from "src/interfaces/IIndexRegistry.sol"; -import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; -import {BitmapUtils} from "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; +import "src/interfaces/IStakeRegistry.sol"; +import "src/interfaces/IBLSPubkeyRegistry.sol"; +import "src/interfaces/IIndexRegistry.sol"; +import "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; /** * @title BLSOperatorStateRetriever with view functions that allow to retrieve the state of an AVSs registry system. diff --git a/src/BLSPubkeyRegistryStorage.sol b/src/BLSPubkeyRegistryStorage.sol index f70a037a..22d4751a 100644 --- a/src/BLSPubkeyRegistryStorage.sol +++ b/src/BLSPubkeyRegistryStorage.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; -import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; -import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; -import {IBLSPublicKeyCompendium} from "src/interfaces/IBLSPublicKeyCompendium.sol"; -import {BN254} from "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; +import "src/interfaces/IBLSPubkeyRegistry.sol"; +import "src/interfaces/IRegistryCoordinator.sol"; +import "src/interfaces/IBLSPublicKeyCompendium.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; diff --git a/src/BLSRegistryCoordinatorWithIndices.sol b/src/BLSRegistryCoordinatorWithIndices.sol index 0404891b..33dd131f 100644 --- a/src/BLSRegistryCoordinatorWithIndices.sol +++ b/src/BLSRegistryCoordinatorWithIndices.sol @@ -4,21 +4,21 @@ pragma solidity =0.8.12; import "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; -import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; -import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; -import {BN254} from "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; -import {EIP1271SignatureUtils} from "eigenlayer-contracts/src/contracts/libraries/EIP1271SignatureUtils.sol"; -import {BitmapUtils} from "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; -import {Pausable} from "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; - -import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; -import {ISocketUpdater} from "src/interfaces/ISocketUpdater.sol"; -import {IServiceManager} from "src/interfaces/IServiceManager.sol"; -import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; -import {IVoteWeigher} from "src/interfaces/IVoteWeigher.sol"; -import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; -import {IIndexRegistry} from "src/interfaces/IIndexRegistry.sol"; -import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; +import "eigenlayer-contracts/src/contracts/libraries/EIP1271SignatureUtils.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; +import "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; + +import "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; +import "src/interfaces/ISocketUpdater.sol"; +import "src/interfaces/IServiceManager.sol"; +import "src/interfaces/IBLSPubkeyRegistry.sol"; +import "src/interfaces/IVoteWeigher.sol"; +import "src/interfaces/IStakeRegistry.sol"; +import "src/interfaces/IIndexRegistry.sol"; +import "src/interfaces/IRegistryCoordinator.sol"; diff --git a/src/BLSSignatureChecker.sol b/src/BLSSignatureChecker.sol index bddcbd5b..fdad60a9 100644 --- a/src/BLSSignatureChecker.sol +++ b/src/BLSSignatureChecker.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; -import {IBLSSignatureChecker} from "src/interfaces/IBLSSignatureChecker.sol"; -import {BitmapUtils} from "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; -import {BN254} from "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; -import {IRegistryCoordinator} from "src/interfaces/IRegistryCoordinator.sol"; -import {IStakeRegistry} from "src/interfaces/IStakeRegistry.sol"; -import {IBLSPubkeyRegistry} from "src/interfaces/IBLSPubkeyRegistry.sol"; -import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; +import "src/interfaces/IBLSSignatureChecker.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BitmapUtils.sol"; +import "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; +import "src/interfaces/IRegistryCoordinator.sol"; +import "src/interfaces/IStakeRegistry.sol"; +import "src/interfaces/IBLSPubkeyRegistry.sol"; +import "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; /** * @title Used for checking BLS aggregate signatures from the operators of a `BLSRegistry`. diff --git a/src/ServiceManagerBase.sol b/src/ServiceManagerBase.sol index 92e3371a..b49373ee 100644 --- a/src/ServiceManagerBase.sol +++ b/src/ServiceManagerBase.sol @@ -3,15 +3,15 @@ pragma solidity ^0.8.9; import "@openzeppelin-upgrades/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin-upgrades/contracts/access/OwnableUpgradeable.sol"; -import {BLSSignatureChecker} from "src/BLSSignatureChecker.sol"; -import {IBLSRegistryCoordinatorWithIndices} from "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; -import {IServiceManager} from "src/interfaces/IServiceManager.sol"; +import "src/BLSSignatureChecker.sol"; +import "src/interfaces/IBLSRegistryCoordinatorWithIndices.sol"; +import "src/interfaces/IServiceManager.sol"; -import {Pausable} from "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; -import {IPauserRegistry} from "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; -import {IDelegationManager} from "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; -import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; -import {IStrategyManager} from "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; +import "eigenlayer-contracts/src/contracts/permissions/Pausable.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IPauserRegistry.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; +import "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; /** * @title Base implementation of `IServiceManager` interface, designed to be inherited from by more complex ServiceManagers. diff --git a/src/interfaces/IRegistry.sol b/src/interfaces/IRegistry.sol index 49e7d545..0b8bb3c0 100644 --- a/src/interfaces/IRegistry.sol +++ b/src/interfaces/IRegistry.sol @@ -1,15 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; -import "./IRegistryCoordinator.sol"; - -/** - * @title Minimal interface for a `Registry`-type contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice Functions related to the registration process itself have been intentionally excluded - * because their function signatures may vary significantly. - */ -interface IRegistry { - function registryCoordinator() external view returns (IRegistryCoordinator); -} +import "eigenlayer-contracts/src/contracts/interfaces/IRegistry.sol"; diff --git a/src/interfaces/IRegistryCoordinator.sol b/src/interfaces/IRegistryCoordinator.sol index 3ee5b1a9..7bbad67e 100644 --- a/src/interfaces/IRegistryCoordinator.sol +++ b/src/interfaces/IRegistryCoordinator.sol @@ -1,97 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; -/** - * @title Interface for a contract that coordinates between various registries for an AVS. - * @author Layr Labs, Inc. - */ -interface IRegistryCoordinator { - // EVENTS - /// Emits when an operator is registered - event OperatorRegistered(address indexed operator, bytes32 indexed operatorId); - - /// Emits when an operator is deregistered - event OperatorDeregistered(address indexed operator, bytes32 indexed operatorId); - - // DATA STRUCTURES - enum OperatorStatus - { - // default is NEVER_REGISTERED - NEVER_REGISTERED, - REGISTERED, - DEREGISTERED - } - - // STRUCTS - - /** - * @notice Data structure for storing info on operators - */ - struct Operator { - // the id of the operator, which is likely the keccak256 hash of the operator's public key if using BLSRegsitry - bytes32 operatorId; - // indicates whether the operator is actively registered for serving the middleware or not - OperatorStatus status; - } - - /** - * @notice Data structure for storing info on quorum bitmap updates where the `quorumBitmap` is the bitmap of the - * quorums the operator is registered for starting at (inclusive)`updateBlockNumber` and ending at (exclusive) `nextUpdateBlockNumber` - * @dev nextUpdateBlockNumber is initialized to 0 for the latest update - */ - struct QuorumBitmapUpdate { - uint32 updateBlockNumber; - uint32 nextUpdateBlockNumber; - uint192 quorumBitmap; - } - - /// @notice Returns the operator struct for the given `operator` - function getOperator(address operator) external view returns (Operator memory); - - /// @notice Returns the operatorId for the given `operator` - function getOperatorId(address operator) external view returns (bytes32); - - /// @notice Returns the operator address for the given `operatorId` - function getOperatorFromId(bytes32 operatorId) external view returns (address operator); - - /// @notice Returns the status for the given `operator` - function getOperatorStatus(address operator) external view returns (IRegistryCoordinator.OperatorStatus); - - /// @notice Returns the indices of the quorumBitmaps for the provided `operatorIds` at the given `blockNumber` - function getQuorumBitmapIndicesByOperatorIdsAtBlockNumber(uint32 blockNumber, bytes32[] memory operatorIds) external view returns (uint32[] memory); - - /** - * @notice Returns the quorum bitmap for the given `operatorId` at the given `blockNumber` via the `index` - * @dev reverts if `index` is incorrect - */ - function getQuorumBitmapByOperatorIdAtBlockNumberByIndex(bytes32 operatorId, uint32 blockNumber, uint256 index) external view returns (uint192); - - /// @notice Returns the `index`th entry in the operator with `operatorId`'s bitmap history - function getQuorumBitmapUpdateByOperatorIdByIndex(bytes32 operatorId, uint256 index) external view returns (QuorumBitmapUpdate memory); - - /// @notice Returns the current quorum bitmap for the given `operatorId` - function getCurrentQuorumBitmapByOperatorId(bytes32 operatorId) external view returns (uint192); - - /// @notice Returns the length of the quorum bitmap history for the given `operatorId` - function getQuorumBitmapUpdateByOperatorIdLength(bytes32 operatorId) external view returns (uint256); - - /// @notice Returns the registry at the desired index - function registries(uint256) external view returns (address); - - /// @notice Returns the number of registries - function numRegistries() external view returns (uint256); - - /** - * @notice Registers msg.sender as an operator with the middleware - * @param quorumNumbers are the bytes representing the quorum numbers that the operator is registering for - * @param registrationData is the data that is decoded to get the operator's registration information - */ - function registerOperatorWithCoordinator(bytes memory quorumNumbers, bytes calldata registrationData) external; - - /** - * @notice Deregisters the msg.sender as an operator from the middleware - * @param quorumNumbers are the bytes representing the quorum numbers that the operator is registered for - * @param deregistrationData is the the data that is decoded to get the operator's deregistration information - */ - function deregisterOperatorWithCoordinator(bytes calldata quorumNumbers, bytes calldata deregistrationData) external; -} \ No newline at end of file +import "eigenlayer-contracts/src/contracts/interfaces/IRegistryCoordinator.sol"; diff --git a/src/interfaces/IServiceManager.sol b/src/interfaces/IServiceManager.sol index 5a36f7da..378f82b8 100644 --- a/src/interfaces/IServiceManager.sol +++ b/src/interfaces/IServiceManager.sol @@ -1,39 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {ISlasher} from "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; - -/** - * @title Interface for a `ServiceManager`-type contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - */ -interface IServiceManager { - - // ServiceManager proxies to the slasher - function slasher() external view returns (ISlasher); - - /// @notice Returns the current 'taskNumber' for the middleware - function taskNumber() external view returns (uint32); - - /// @notice function that causes the ServiceManager to freeze the operator on EigenLayer, through a call to the Slasher contract - /// @dev this function should contain slashing logic, to make sure operators are not needlessly being slashed - function freezeOperator(address operator) external; - - /// @notice proxy call to the slasher, recording an initial stake update (on operator registration) - function recordFirstStakeUpdate(address operator, uint32 serveUntilBlock) external; - - /// @notice proxy call to the slasher, recording a stake update - function recordStakeUpdate(address operator, uint32 updateBlock, uint32 serveUntilBlock, uint256 prevElement) external; - - /// @notice proxy call to the slasher, recording a final stake update (on operator deregistration) - function recordLastStakeUpdateAndRevokeSlashingAbility(address operator, uint32 serveUntilBlock) external; - - /// @notice Returns the latest block until which operators must serve (could be in the past or future). - /// @dev this should be called and the response passed to the recordStakeUpdate functionss' serveUntilBlock parameter - function latestServeUntilBlock() external view returns (uint32); - - /// @notice required since the registry contract will call this function to permission its upgrades to be done by the same owner as the service manager - function owner() external view returns (address); -} +import "eigenlayer-contracts/src/contracts/interfaces/IServiceManager.sol"; diff --git a/src/interfaces/IStakeRegistry.sol b/src/interfaces/IStakeRegistry.sol index 4420d58d..713df01e 100644 --- a/src/interfaces/IStakeRegistry.sol +++ b/src/interfaces/IStakeRegistry.sol @@ -1,160 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.8.12; -import {IRegistry} from "src/interfaces/IRegistry.sol"; - -/** - * @title Interface for a `Registry` that keeps track of stakes of operators for up to 256 quorums. - * @author Layr Labs, Inc. - */ -interface IStakeRegistry is IRegistry { - // EVENTS - /// @notice emitted whenever the stake of `operator` is updated - event StakeUpdate( - bytes32 indexed operatorId, - uint8 quorumNumber, - uint96 stake - ); - - // DATA STRUCTURES - - /// @notice struct used to store the stakes of an individual operator or the sum of all operators' stakes, for storage - struct OperatorStakeUpdate { - // the block number at which the stake amounts were updated and stored - uint32 updateBlockNumber; - // the block number at which the *next update* occurred. - /// @notice This entry has the value **0** until another update takes place. - uint32 nextUpdateBlockNumber; - // stake weight for the quorum - uint96 stake; - } - - // EVENTS - event MinimumStakeForQuorumUpdated(uint8 indexed quorumNumber, uint96 minimumStake); - - /** - * @notice Registers the `operator` with `operatorId` for the specified `quorumNumbers`. - * @param operator The address of the operator to register. - * @param operatorId The id of the operator to register. - * @param quorumNumbers The quorum numbers the operator is registering for, where each byte is an 8 bit integer quorumNumber. - * @dev access restricted to the RegistryCoordinator - * @dev Preconditions (these are assumed, not validated in this contract): - * 1) `quorumNumbers` has no duplicates - * 2) `quorumNumbers.length` != 0 - * 3) `quorumNumbers` is ordered in ascending order - * 4) the operator is not already registered - */ - function registerOperator(address operator, bytes32 operatorId, bytes memory quorumNumbers) external; - - /** - * @notice Deregisters the operator with `operatorId` for the specified `quorumNumbers`. - * @param operatorId The id of the operator to deregister. - * @param quorumNumbers The quorum numbers the operator is deregistering from, where each byte is an 8 bit integer quorumNumber. - * @dev access restricted to the RegistryCoordinator - * @dev Preconditions (these are assumed, not validated in this contract): - * 1) `quorumNumbers` has no duplicates - * 2) `quorumNumbers.length` != 0 - * 3) `quorumNumbers` is ordered in ascending order - * 4) the operator is not already deregistered - * 5) `quorumNumbers` is a subset of the quorumNumbers that the operator is registered for - */ - function deregisterOperator(bytes32 operatorId, bytes memory quorumNumbers) external; - - /// @notice In order to register for a quorum i, an operator must have at least `minimumStakeForQuorum[i]` - function minimumStakeForQuorum(uint256 quorumNumber) external view returns (uint96); - - /** - * @notice Returns the entire `operatorIdToStakeHistory[operatorId][quorumNumber]` array. - * @param operatorId The id of the operator of interest. - * @param quorumNumber The quorum number to get the stake for. - */ - function getOperatorIdToStakeHistory(bytes32 operatorId, uint8 quorumNumber) external view returns (OperatorStakeUpdate[] memory); - - function getLengthOfTotalStakeHistoryForQuorum(uint8 quorumNumber) external view returns (uint256); - - /** - * @notice Returns the `index`-th entry in the dynamic array of total stake, `totalStakeHistory` for quorum `quorumNumber`. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `totalStakeHistory[quorumNumber]`. - */ - function getTotalStakeUpdateForQuorumFromIndex(uint8 quorumNumber, uint256 index) external view returns (OperatorStakeUpdate memory); - - /// @notice Returns the indices of the operator stakes for the provided `quorumNumber` at the given `blockNumber` - function getStakeUpdateIndexForOperatorIdForQuorumAtBlockNumber(bytes32 operatorId, uint8 quorumNumber, uint32 blockNumber) - external - view - returns (uint32); - - /// @notice Returns the indices of the total stakes for the provided `quorumNumbers` at the given `blockNumber` - function getTotalStakeIndicesByQuorumNumbersAtBlockNumber(uint32 blockNumber, bytes calldata quorumNumbers) external view returns(uint32[] memory) ; - - /** - * @notice Returns the `index`-th entry in the `operatorIdToStakeHistory[operatorId][quorumNumber]` array. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorIdToStakeHistory[operatorId][quorumNumber]`. - * @dev Function will revert if `index` is out-of-bounds. - */ - function getStakeUpdateForQuorumFromOperatorIdAndIndex(uint8 quorumNumber, bytes32 operatorId, uint256 index) - external - view - returns (OperatorStakeUpdate memory); - - /** - * @notice Returns the most recent stake weight for the `operatorId` for a certain quorum - * @dev Function returns an OperatorStakeUpdate struct with **every entry equal to 0** in the event that the operator has no stake history - */ - function getMostRecentStakeUpdateByOperatorId(bytes32 operatorId, uint8 quorumNumber) external view returns (OperatorStakeUpdate memory); - - /** - * @notice Returns the stake weight corresponding to `operatorId` for quorum `quorumNumber`, at the - * `index`-th entry in the `operatorIdToStakeHistory[operatorId][quorumNumber]` array if the entry - * corresponds to the operator's stake at `blockNumber`. Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param operatorId The id of the operator of interest. - * @param index Array index for lookup, within the dynamic array `operatorIdToStakeHistory[operatorId][quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - * @dev used the BLSSignatureChecker to get past stakes of signing operators - */ - function getStakeForQuorumAtBlockNumberFromOperatorIdAndIndex(uint8 quorumNumber, uint32 blockNumber, bytes32 operatorId, uint256 index) - external - view - returns (uint96); - - /** - * @notice Returns the total stake weight for quorum `quorumNumber`, at the `index`-th entry in the - * `totalStakeHistory[quorumNumber]` array if the entry corresponds to the total stake at `blockNumber`. - * Reverts otherwise. - * @param quorumNumber The quorum number to get the stake for. - * @param index Array index for lookup, within the dynamic array `totalStakeHistory[quorumNumber]`. - * @param blockNumber Block number to make sure the stake is from. - * @dev Function will revert if `index` is out-of-bounds. - * @dev used the BLSSignatureChecker to get past stakes of signing operators - */ - function getTotalStakeAtBlockNumberFromIndex(uint8 quorumNumber, uint32 blockNumber, uint256 index) external view returns (uint96); - - /** - * @notice Returns the most recent stake weight for the `operatorId` for quorum `quorumNumber` - * @dev Function returns weight of **0** in the event that the operator has no stake history - */ - function getCurrentOperatorStakeForQuorum(bytes32 operatorId, uint8 quorumNumber) external view returns (uint96); - - /// @notice Returns the stake of the operator for the provided `quorumNumber` at the given `blockNumber` - function getStakeForOperatorIdForQuorumAtBlockNumber(bytes32 operatorId, uint8 quorumNumber, uint32 blockNumber) - external - view - returns (uint96); - - /** - * @notice Returns the stake weight from the latest entry in `_totalStakeHistory` for quorum `quorumNumber`. - * @dev Will revert if `_totalStakeHistory[quorumNumber]` is empty. - */ - function getCurrentTotalStakeForQuorum(uint8 quorumNumber) external view returns (uint96); - - /** - * @notice Used for updating information on deposits of nodes. - * @param operators are the addresses of the operators whose stake information is getting updated - */ - function updateStakes(address[] memory operators) external; -} +import "eigenlayer-contracts/src/contracts/interfaces/IStakeRegistry.sol"; diff --git a/src/interfaces/IVoteWeigher.sol b/src/interfaces/IVoteWeigher.sol index 1059eccc..4ae103cb 100644 --- a/src/interfaces/IVoteWeigher.sol +++ b/src/interfaces/IVoteWeigher.sol @@ -1,96 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; -import "eigenlayer-contracts/src/contracts/interfaces/IStrategyManager.sol"; -import "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol"; -import "src/interfaces/IServiceManager.sol"; -import "eigenlayer-contracts/src/contracts/interfaces/ISlasher.sol"; -import "eigenlayer-contracts/src/contracts/interfaces/IDelegationManager.sol"; - -/** - * @title Interface for a `VoteWeigher`-type contract. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice Note that `NUMBER_OF_QUORUMS` is expected to remain constant, as suggested by its uppercase formatting. - */ -interface IVoteWeigher { - /// @notice emitted when a new quorum is created - event QuorumCreated(uint8 indexed quorumNumber); - /// @notice emitted when `strategy` has been added to the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyAddedToQuorum(uint8 indexed quorumNumber, IStrategy strategy); - /// @notice emitted when `strategy` has removed from the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyRemovedFromQuorum(uint8 indexed quorumNumber, IStrategy strategy); - /// @notice emitted when `strategy` has its `multiplier` updated in the array at `strategiesConsideredAndMultipliers[quorumNumber]` - event StrategyMultiplierUpdated(uint8 indexed quorumNumber, IStrategy strategy, uint256 multiplier); - - /** - * @notice In weighing a particular strategy, the amount of underlying asset for that strategy is - * multiplied by its multiplier, then divided by WEIGHTING_DIVISOR - */ - struct StrategyAndWeightingMultiplier { - IStrategy strategy; - uint96 multiplier; - } - - /// @notice Constant used as a divisor in calculating weights. - function WEIGHTING_DIVISOR() external pure returns (uint256); - - /// @notice Returns the EigenLayer strategy manager contract. - function strategyManager() external view returns (IStrategyManager); - /// @notice Returns the EigenLayer slasher contract. - function slasher() external view returns (ISlasher); - /// @notice Returns the EigenLayer delegation manager contract. - function delegation() external view returns (IDelegationManager); - /// @notice Returns the AVS service manager contract. - function serviceManager() external view returns (IServiceManager); - - /** - * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. - * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` - */ - function weightOfOperatorForQuorum(uint8 quorumNumber, address operator) external view returns (uint96); - - /// @notice Number of quorums that are being used by the middleware. - function quorumCount() external view returns (uint16); - - /// @notice Returns the strategy and weight multiplier for the `index`'th strategy in the quorum `quorumNumber` - function strategyAndWeightingMultiplierForQuorumByIndex(uint8 quorumNumber, uint256 index) external view returns (StrategyAndWeightingMultiplier memory); - - /// @notice Create a new quorum and add the strategies and their associated weights to the quorum. - function createQuorum( - StrategyAndWeightingMultiplier[] memory _strategiesConsideredAndMultipliers - ) external; - - /// @notice Adds new strategies and the associated multipliers to the @param quorumNumber. - function addStrategiesConsideredAndMultipliers( - uint8 quorumNumber, - StrategyAndWeightingMultiplier[] memory _newStrategiesConsideredAndMultipliers - ) external; - - /** - * @notice This function is used for removing strategies and their associated weights from the - * mapping strategiesConsideredAndMultipliers for a specific @param quorumNumber. - * @dev higher indices should be *first* in the list of @param indicesToRemove, since otherwise - * the removal of lower index entries will cause a shift in the indices of the other strategiesToRemove - */ - function removeStrategiesConsideredAndMultipliers( - uint8 quorumNumber, - uint256[] calldata indicesToRemove - ) external; - - /** - * @notice This function is used for modifying the weights of strategies that are already in the - * mapping strategiesConsideredAndMultipliers for a specific - * @param quorumNumber is the quorum number to change the strategy for - * @param strategyIndices are the indices of the strategies to change - * @param newMultipliers are the new multipliers for the strategies - */ - function modifyStrategyWeights( - uint8 quorumNumber, - uint256[] calldata strategyIndices, - uint96[] calldata newMultipliers - ) external; - - /// @notice Returns the length of the dynamic array stored in `strategiesConsideredAndMultipliers[quorumNumber]`. - function strategiesConsideredAndMultipliersLength(uint8 quorumNumber) external view returns (uint256); -} +import "eigenlayer-contracts/src/contracts/interfaces/IVoteWeigher.sol"; From 84b5a5df09b90cd1a8958441f7b637ff0595c2df Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 20 Oct 2023 12:32:01 -0400 Subject: [PATCH 4/6] add view methods for compatability with core temporarily --- src/VoteWeigherBase.sol | 6 ++++++ test/harnesses/StakeRegistryHarness.sol | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/VoteWeigherBase.sol b/src/VoteWeigherBase.sol index 0be3d60e..24e06faf 100644 --- a/src/VoteWeigherBase.sol +++ b/src/VoteWeigherBase.sol @@ -192,6 +192,12 @@ contract VoteWeigherBase is VoteWeigherBaseStorage { return strategiesConsideredAndMultipliers[quorumNumber][index]; } + + /// TODO remove when core gets updated + function weightOfOperatorForQuorumView( + uint8 quorumNumber, + address operator + ) public virtual view validQuorumNumber(quorumNumber) returns (uint96) {} /** * @notice This function computes the total weight of the @param operator in the quorum @param quorumNumber. * @dev reverts in the case that `quorumNumber` is greater than or equal to `quorumCount` diff --git a/test/harnesses/StakeRegistryHarness.sol b/test/harnesses/StakeRegistryHarness.sol index 4cc8be9d..1a61a47b 100644 --- a/test/harnesses/StakeRegistryHarness.sol +++ b/test/harnesses/StakeRegistryHarness.sol @@ -31,6 +31,11 @@ contract StakeRegistryHarness is StakeRegistry { return _weightOfOperatorForQuorum[quorumNumber][operator]; } + /// TODO remove when core gets updated + function weightOfOperatorForQuorumView(uint8 quorumNumber, address operator) public override view returns(uint96) { + return _weightOfOperatorForQuorum[quorumNumber][operator]; + } + // mocked function so we can set this arbitrarily without having to mock other elements function setOperatorWeight(uint8 quorumNumber, address operator, uint96 weight) external { _weightOfOperatorForQuorum[quorumNumber][operator] = weight; From 1aacc07ec465dbd433d848925313bb0dda687d1a Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 20 Oct 2023 12:54:23 -0400 Subject: [PATCH 5/6] IBLSRegistry --- src/interfaces/IBLSRegistry.sol | 68 +-------------------------------- 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/src/interfaces/IBLSRegistry.sol b/src/interfaces/IBLSRegistry.sol index 1d366b5a..6e787968 100644 --- a/src/interfaces/IBLSRegistry.sol +++ b/src/interfaces/IBLSRegistry.sol @@ -1,70 +1,4 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity >=0.5.0; -import "src/interfaces/IQuorumRegistry.sol"; -import {BN254} from "eigenlayer-contracts/src/contracts/libraries/BN254.sol"; - - -/** - * @title Minimal interface extension to `IQuorumRegistry`. - * @author Layr Labs, Inc. - * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service - * @notice Adds BLS-specific functions to the base interface. - */ -interface IBLSRegistry is IQuorumRegistry { - /// @notice Data structure used to track the history of the Aggregate Public Key of all operators - struct ApkUpdate { - // keccak256(apk_x0, apk_x1, apk_y0, apk_y1) - bytes32 apkHash; - // block number at which the update occurred - uint32 blockNumber; - } - - // EVENTS - /** - * @notice Emitted upon the registration of a new operator for the middleware - * @param operator Address of the new operator - * @param pkHash The keccak256 hash of the operator's public key - * @param pk The operator's public key itself - * @param apkHashIndex The index of the latest (i.e. the new) APK update - * @param apkHash The keccak256 hash of the new Aggregate Public Key - */ - event Registration( - address indexed operator, - bytes32 pkHash, - BN254.G1Point pk, - uint32 apkHashIndex, - bytes32 apkHash, - string socket - ); - - /// @notice Emitted when the `operatorWhitelister` role is transferred. - event OperatorWhitelisterTransferred(address previousAddress, address newAddress); - - /** - * @notice get hash of a historical aggregated public key corresponding to a given index; - * called by checkSignatures in BLSSignatureChecker.sol. - */ - function getCorrectApkHash(uint256 index, uint32 blockNumber) external returns (bytes32); - - /// @notice returns the `ApkUpdate` struct at `index` in the list of APK updates - function apkUpdates(uint256 index) external view returns (ApkUpdate memory); - - /// @notice returns the APK hash that resulted from the `index`th APK update - function apkHashes(uint256 index) external view returns (bytes32); - - /// @notice returns the block number at which the `index`th APK update occurred - function apkUpdateBlockNumbers(uint256 index) external view returns (uint32); - - function operatorWhitelister() external view returns (address); - - function operatorWhitelistEnabled() external view returns (bool); - - function whitelisted(address) external view returns (bool); - - function setOperatorWhitelistStatus(bool _operatorWhitelistEnabled) external; - - function addToOperatorWhitelist(address[] calldata) external; - - function removeFromWhitelist(address[] calldata operators) external; -} +import "eigenlayer-contracts/src/contracts/interfaces/IBLSRegistry.sol"; From 43780f401414b190febda3c83f62b6c1783ca148 Mon Sep 17 00:00:00 2001 From: steven Date: Fri, 20 Oct 2023 14:00:14 -0400 Subject: [PATCH 6/6] move back to core --- script/DeployOpenEigenLayer.s.sol | 204 ------------------------------ 1 file changed, 204 deletions(-) delete mode 100644 script/DeployOpenEigenLayer.s.sol diff --git a/script/DeployOpenEigenLayer.s.sol b/script/DeployOpenEigenLayer.s.sol deleted file mode 100644 index 0e852a88..00000000 --- a/script/DeployOpenEigenLayer.s.sol +++ /dev/null @@ -1,204 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 -pragma solidity =0.8.12; - -import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; -import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; -import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; -import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; - -import "eigenlayer-contracts/src/contracts/interfaces/IETHPOSDeposit.sol"; -import "eigenlayer-contracts/src/contracts/interfaces/IBeaconChainOracle.sol"; - -import "eigenlayer-contracts/src/contracts/core/StrategyManager.sol"; -import "eigenlayer-contracts/src/contracts/core/Slasher.sol"; -import "eigenlayer-contracts/src/contracts/core/DelegationManager.sol"; - -import "eigenlayer-contracts/src/contracts/strategies/StrategyBaseTVLLimits.sol"; - -import "eigenlayer-contracts/src/contracts/pods/EigenPod.sol"; -import "eigenlayer-contracts/src/contracts/pods/EigenPodManager.sol"; -import "eigenlayer-contracts/src/contracts/pods/DelayedWithdrawalRouter.sol"; - -import "eigenlayer-contracts/src/contracts/permissions/PauserRegistry.sol"; -import "src/BLSPublicKeyCompendium.sol"; - -import "eigenlayer-contracts/src/test/mocks/EmptyContract.sol"; -import "eigenlayer-contracts/src/test/mocks/ETHDepositMock.sol"; - -import "forge-std/Script.sol"; -import "forge-std/Test.sol"; - -// # To load the variables in the .env file -// source .env - -// # To deploy and verify our contract -// forge script script/M1_Deploy.s.sol:Deployer_M1 --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vvvv -contract DeployOpenEigenLayer is Script, Test { - Vm cheats = Vm(HEVM_ADDRESS); - - // struct used to encode token info in config file - struct StrategyConfig { - uint256 maxDeposits; - uint256 maxPerDeposit; - address tokenAddress; - string tokenSymbol; - } - - // EigenLayer Contracts - ProxyAdmin public eigenLayerProxyAdmin; - PauserRegistry public eigenLayerPauserReg; - Slasher public slasher; - Slasher public slasherImplementation; - DelegationManager public delegation; - DelegationManager public delegationImplementation; - StrategyManager public strategyManager; - StrategyManager public strategyManagerImplementation; - EigenPodManager public eigenPodManager; - EigenPodManager public eigenPodManagerImplementation; - DelayedWithdrawalRouter public delayedWithdrawalRouter; - DelayedWithdrawalRouter public delayedWithdrawalRouterImplementation; - UpgradeableBeacon public eigenPodBeacon; - EigenPod public eigenPodImplementation; - StrategyBase public baseStrategyImplementation; - - EmptyContract public emptyContract; - - // the ETH2 deposit contract -- if not on mainnet, we deploy a mock as stand-in - IETHPOSDeposit public ethPOSDeposit; - - // strategies deployed - StrategyBaseTVLLimits[] public deployedStrategyArray; - - function _deployEigenLayer(address executorMultisig, address operationsMultisig, address pauserMultisig, StrategyConfig[] memory strategyConfigs) internal { - require(executorMultisig != address(0), "executorMultisig address not configured correctly!"); - require(operationsMultisig != address(0), "operationsMultisig address not configured correctly!"); - - // deploy proxy admin for ability to upgrade proxy contracts - eigenLayerProxyAdmin = new ProxyAdmin(); - - //deploy pauser registry - { - address[] memory pausers = new address[](3); - pausers[0] = executorMultisig; - pausers[1] = operationsMultisig; - pausers[2] = pauserMultisig; - eigenLayerPauserReg = new PauserRegistry(pausers, executorMultisig); - } - - /** - * First, deploy upgradeable proxy contracts that **will point** to the implementations. Since the implementation contracts are - * not yet deployed, we give these proxies an empty contract as the initial implementation, to act as if they have no code. - */ - emptyContract = new EmptyContract(); - delegation = DelegationManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - strategyManager = StrategyManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - slasher = Slasher( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - eigenPodManager = EigenPodManager( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - delayedWithdrawalRouter = DelayedWithdrawalRouter( - address(new TransparentUpgradeableProxy(address(emptyContract), address(eigenLayerProxyAdmin), "")) - ); - - // ETH POS deposit is 0 address - eigenPodImplementation = new EigenPod( - ethPOSDeposit, - delayedWithdrawalRouter, - eigenPodManager, - // uint64(MAX_VALIDATOR_BALANCE_GWEI), - uint64(31 gwei), - // uint64(EFFECTIVE_RESTAKED_BALANCE_OFFSET_GWEI) - uint64(0.75 gwei), - 1000 // temp genesis time - ); - - eigenPodBeacon = new UpgradeableBeacon(address(eigenPodImplementation)); - - // Second, deploy the *implementation* contracts, using the *proxy contracts* as inputs - delegationImplementation = new DelegationManager(strategyManager, slasher, eigenPodManager); - strategyManagerImplementation = new StrategyManager(delegation, eigenPodManager, slasher); - slasherImplementation = new Slasher(strategyManager, delegation); - eigenPodManagerImplementation = new EigenPodManager(ethPOSDeposit, eigenPodBeacon, strategyManager, slasher, delegation); - delayedWithdrawalRouterImplementation = new DelayedWithdrawalRouter(eigenPodManager); - - // Third, upgrade the proxy contracts to use the correct implementation contracts and initialize them. - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delegation))), - address(delegationImplementation), - abi.encodeWithSelector( - DelegationManager.initialize.selector, - executorMultisig, - eigenLayerPauserReg, - 0 - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(strategyManager))), - address(strategyManagerImplementation), - abi.encodeWithSelector( - StrategyManager.initialize.selector, - executorMultisig, - operationsMultisig, - eigenLayerPauserReg, - 0, - 0 - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(slasher))), - address(slasherImplementation), - abi.encodeWithSelector( - Slasher.initialize.selector, - executorMultisig, - eigenLayerPauserReg, - 0 - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(eigenPodManager))), - address(eigenPodManagerImplementation), - abi.encodeWithSelector( - EigenPodManager.initialize.selector, - type(uint256).max, - IBeaconChainOracle(address(0)), - executorMultisig, - eigenLayerPauserReg, - 0 - ) - ); - eigenLayerProxyAdmin.upgradeAndCall( - TransparentUpgradeableProxy(payable(address(delayedWithdrawalRouter))), - address(delayedWithdrawalRouterImplementation), - abi.encodeWithSelector(DelayedWithdrawalRouter.initialize.selector, - executorMultisig, - eigenLayerPauserReg, - 0, - 0 - ) - ); - - // deploy StrategyBaseTVLLimits contract implementation - baseStrategyImplementation = new StrategyBaseTVLLimits(strategyManager); - // create upgradeable proxies that each point to the implementation and initialize them - for (uint256 i = 0; i < strategyConfigs.length; ++i) { - deployedStrategyArray.push( - StrategyBaseTVLLimits(address( - new TransparentUpgradeableProxy( - address(baseStrategyImplementation), - address(eigenLayerProxyAdmin), - abi.encodeWithSelector(StrategyBaseTVLLimits.initialize.selector, strategyConfigs[i].maxPerDeposit, strategyConfigs[i].maxDeposits, IERC20(strategyConfigs[i].tokenAddress), eigenLayerPauserReg) - ) - )) - ); - } - - eigenLayerProxyAdmin.transferOwnership(executorMultisig); - eigenPodBeacon.transferOwnership(executorMultisig); - } -}