From b46d23d1c0ed9cfa8d90618d974a0c77d49f8b08 Mon Sep 17 00:00:00 2001 From: Michael Sun <35479365+8sunyuan@users.noreply.github.com> Date: Thu, 9 May 2024 21:26:25 -0400 Subject: [PATCH] EigenDASM Payments Upgrade script (#548) Co-authored-by: QUAQ --- contracts/lib/eigenlayer-middleware | 2 +- .../holesky/EigenDASM_PaymentsUpgrade.s.sol | 196 ++++++++++++++++++ .../config/eigenlayer_preprod.config.json | 58 ++++++ .../eigenlayer_preprod_addresses.config.json | 48 +++++ 4 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 contracts/script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol create mode 100644 contracts/script/deploy/holesky/config/eigenlayer_preprod.config.json create mode 100644 contracts/script/deploy/holesky/config/eigenlayer_preprod_addresses.config.json diff --git a/contracts/lib/eigenlayer-middleware b/contracts/lib/eigenlayer-middleware index 74c86d21ba..c5b419a82f 160000 --- a/contracts/lib/eigenlayer-middleware +++ b/contracts/lib/eigenlayer-middleware @@ -1 +1 @@ -Subproject commit 74c86d21ba6dcdc060a01f9933085076f9f6facd +Subproject commit c5b419a82fcca1b64aacd32026ce8d4459b80e35 diff --git a/contracts/script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol b/contracts/script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol new file mode 100644 index 0000000000..581f4292c7 --- /dev/null +++ b/contracts/script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.12; + +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ERC20PresetFixedSupply} from "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; +import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; +import { + ExistingDeploymentParser, + PaymentCoordinator, + IPaymentCoordinator, + IPauserRegistry, + IStrategy, + IERC20 +} from "eigenlayer-scripts/utils/ExistingDeploymentParser.sol"; +import {IRegistryCoordinator} from "eigenlayer-middleware/interfaces/IRegistryCoordinator.sol"; +import {IStakeRegistry} from "eigenlayer-middleware/interfaces/IStakeRegistry.sol"; + +import {EigenDAServiceManager} from "../../../src/core/EigenDAServiceManager.sol"; + +/** + * @title ServiceManagerBaseUpgrade for Preprod contracts. + * Assumes EOA deploying has permissions to call the proxyAdmin to upgrade. + * + * + * Local Fork: Deploy/Upgrade PaymentCoordinator + * anvil --fork-url $RPC_HOLESKY + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" upgrade + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" deploy + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url http://127.0.0.1:8545 --private-key $PRIVATE_KEY --broadcast -vvvv --sig "run(string memory deployArg)" payForRange + * + * Upgrade Holesky testnet: Deploy/Upgrade PaymentCoordinator + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast --verify -vvvv --sig "run(string memory deployArg)" upgrade + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast --verify -vvvv --sig "run(string memory deployArg)" deploy + * forge script script/deploy/holesky/EigenDASM_PaymentsUpgrade.s.sol:ServiceManagerBaseUpgrade --rpc-url $RPC_HOLESKY --private-key $PRIVATE_KEY --broadcast --verify -vvvv --sig "run(string memory deployArg)" payForRange + */ +contract ServiceManagerBaseUpgrade is ExistingDeploymentParser { + // Hardcode these values to your needs + address public serviceManager = 0x54A03db2784E3D0aCC08344D05385d0b62d4F432; + address public serviceManagerImplementation = 0xFe779fB43280A92cd85466312E2AE8A4F1A48007; + ProxyAdmin public avsProxyAdmin = ProxyAdmin(0x9Fd7E279f5bD692Dc04792151E14Ad814FC60eC1); + address deployerAddress = 0xDA29BB71669f46F2a779b4b62f03644A84eE3479; + address registryCoordinator = 0x2c61EA360D6500b58E7f481541A36B443Bc858c6; + address stakeRegistry = 0x53668EBf2e28180e38B122c641BC51Ca81088871; + + function run(string memory deployArg) external { + // 1. Setup and parse existing EigenLayer Holesky preprod contracts + _parseInitialDeploymentParams( + "script/deploy/holesky/config/eigenlayer_preprod.config.json" + ); + _parseDeployedContracts( + "script/deploy/holesky/config/eigenlayer_preprod_addresses.config.json" + ); + + // 2. broadcast deployment + vm.startBroadcast(); + + emit log_named_address("Deployer Address", msg.sender); + + if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("upgrade"))) { + _upgradeServiceManager(); + } else if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("deploy"))) { + _deployServiceManager(); + } else if (keccak256(abi.encode(deployArg)) == keccak256(abi.encode("payForRange"))) { + _payForRange(); + } + + vm.stopBroadcast(); + + // 3. Sanity Checks + _verifyUpgrade(); + + // Verify Eigenlayer contracts parsed from config + _verifyContractPointers(); + _verifyImplementations(); + _verifyContractsInitialized({isInitialDeployment: false}); + _verifyInitializationParams(); + } + + /// @dev Should override this to change to your specific upgrade needs + function _upgradeServiceManager() internal virtual { + // 1. Deploy new ServiceManager implementation contract + serviceManagerImplementation = address( + new EigenDAServiceManager( + avsDirectory, + paymentCoordinator, + IRegistryCoordinator(registryCoordinator), + IStakeRegistry(stakeRegistry) + ) + ); + + // 2. Upgrade the ServiceManager proxy to the new implementation + avsProxyAdmin.upgrade( + TransparentUpgradeableProxy(payable(address(serviceManager))), + address(serviceManagerImplementation) + ); + } + + function _deployServiceManager() internal virtual { + IPauserRegistry pauserRegistry = IPauserRegistry(0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1); + address emptyContract = 0xc08b788d587F927b49665b90ab35D5224965f3d9; + uint256 initialPausedStatus = 0; + address initialOwner = deployerAddress; + address[] memory batchConfirmers; + + // 1. Deploy new ServiceManager implementation contract + serviceManagerImplementation = address( + new EigenDAServiceManager( + avsDirectory, + paymentCoordinator, + IRegistryCoordinator(registryCoordinator), + IStakeRegistry(stakeRegistry) + ) + ); + + // 2. Deploy new TUPS and initialize + serviceManager = address( + new TransparentUpgradeableProxy(emptyContract, address(avsProxyAdmin), "") + ); + + avsProxyAdmin.upgradeAndCall( + TransparentUpgradeableProxy(payable(address(serviceManager))), + address(serviceManagerImplementation), + abi.encodeWithSelector( + EigenDAServiceManager.initialize.selector, + eigenLayerPauserReg, + initialPausedStatus, + initialOwner, + batchConfirmers + ) + ); + } + + /// @notice Example payForRange call with the ServiceManager + function _payForRange() internal { + uint256 mockTokenInitialSupply = 1e30; + address stETHStrategy = 0x5C8b55722f421556a2AAfb7A3EA63d4c3e514312; + address rETHStrategy = 0x87f6C7d24b109919eB38295e3F8298425e6331D9; + + IPaymentCoordinator.StrategyAndMultiplier[] memory strategyAndMultipliers = new IPaymentCoordinator.StrategyAndMultiplier[](2); + // Strategy addresses must be in ascending order + strategyAndMultipliers[0] = IPaymentCoordinator.StrategyAndMultiplier({ + strategy: IStrategy(stETHStrategy), + multiplier: 1e18 + }); + strategyAndMultipliers[1] = IPaymentCoordinator.StrategyAndMultiplier({ + strategy: IStrategy(rETHStrategy), + multiplier: 1e18 + }); + + IERC20 token = new ERC20PresetFixedSupply( + "dog wif hat", + "MOCK1", + mockTokenInitialSupply, + msg.sender + ); + // must be in multiples of weeks i.e startTimestamp % 604800 == 0 + uint32 startTimestamp = 1714608000; + // must be in multiples of weeks i.e duration % 604800 == 0 + uint32 duration = 1 weeks; + // amount <= 1e38 - 1 + uint256 amount = 100e18; + + // 2. Create range payment input param + IPaymentCoordinator.RangePayment[] + memory rangePayments = new IPaymentCoordinator.RangePayment[](1); + rangePayments[0] = IPaymentCoordinator.RangePayment({ + strategiesAndMultipliers: strategyAndMultipliers, + token: token, + amount: amount, + startTimestamp: startTimestamp, + duration: duration + }); + + token.approve(serviceManager, amount); + EigenDAServiceManager(serviceManager).payForRange(rangePayments); + } + + /// @dev check implementation address set properly + function _verifyUpgrade() internal virtual { + // Preprod PaymentCoordinator + require( + address(paymentCoordinator) == 0xb22Ef643e1E067c994019A4C19e403253C05c2B0, + "ServiceManagerBaseUpgrade: PaymentCoordinator address is incorrect" + ); + require( + avsProxyAdmin.getProxyImplementation( + TransparentUpgradeableProxy(payable(serviceManager)) + ) == serviceManagerImplementation, + "ServiceManagerBaseUpgrade: ServiceMananger implementation initially set incorrectly" + ); + require( + msg.sender == deployerAddress, + "ServiceManagerBaseUpgrade: deployer address is incorrect" + ); + } +} diff --git a/contracts/script/deploy/holesky/config/eigenlayer_preprod.config.json b/contracts/script/deploy/holesky/config/eigenlayer_preprod.config.json new file mode 100644 index 0000000000..071b2a7a38 --- /dev/null +++ b/contracts/script/deploy/holesky/config/eigenlayer_preprod.config.json @@ -0,0 +1,58 @@ +{ + "chainInfo": { + "chainId": 17000 + }, + "multisig_addresses": { + "pauserMultisig": "0x53410249ec7d3a3F9F1ba3912D50D6A3Df6d10A7", + "communityMultisig": "0xCb8d2f9e55Bc7B1FA9d089f9aC80C583D2BDD5F7", + "operationsMultisig": "0xfaEF7338b7490b9E272d80A1a39f4657cAf2b97d", + "executorMultisig": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + }, + "strategies": { + "numStrategies": 0, + "MAX_PER_DEPOSIT": 115792089237316195423570985008687907853269984665640564039457584007913129639935, + "MAX_TOTAL_DEPOSITS": 115792089237316195423570985008687907853269984665640564039457584007913129639935, + "strategiesToDeploy": [] + }, + "strategyManager": { + "init_strategy_whitelister": "0x28Ade60640fdBDb2609D8d8734D1b5cBeFc0C348", + "init_paused_status": 0 + }, + "delegationManager": { + "init_paused_status": 0, + "init_minWithdrawalDelayBlocks": 10 + }, + "paymentCoordinator": { + "init_paused_status": 0, + "CALCULATION_INTERVAL_SECONDS": 604800, + "MAX_PAYMENT_DURATION": 6048000, + "MAX_RETROACTIVE_LENGTH": 7776000, + "MAX_FUTURE_LENGTH": 2592000, + "GENESIS_PAYMENT_TIMESTAMP": 1710979200, + "payment_updater_address": "0x02d9bd32ec711AC8782aEaBF9e1E1309F0965c11", + "activation_delay": 120, + "calculation_interval_seconds": 604800, + "global_operator_commission_bips": 1000 + }, + "avsDirectory": { + "init_paused_status": 0 + }, + "slasher": { + "init_paused_status": 0 + }, + "eigenPod": { + "MAX_RESTAKED_BALANCE_GWEI_PER_VALIDATOR": 32000000000, + "GENESIS_TIME": 1695902400 + }, + "eigenPodManager": { + "init_paused_status": 0, + "deneb_fork_timestamp": "1707305664" + }, + "delayedWithdrawalRouter": { + "init_paused_status": 0, + "init_withdrawalDelayBlocks": 10 + }, + "ethPOSDepositAddress": "0x4242424242424242424242424242424242424242", + "beaconOracleAddress": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25" +} \ No newline at end of file diff --git a/contracts/script/deploy/holesky/config/eigenlayer_preprod_addresses.config.json b/contracts/script/deploy/holesky/config/eigenlayer_preprod_addresses.config.json new file mode 100644 index 0000000000..b6bf2c33eb --- /dev/null +++ b/contracts/script/deploy/holesky/config/eigenlayer_preprod_addresses.config.json @@ -0,0 +1,48 @@ +{ + "addresses": { + "avsDirectory": "0x141d6995556135D4997b2ff72EB443Be300353bC", + "avsDirectoryImplementation": "0x357978adC03375BD6a3605DE055fABb84695d79A", + "baseStrategyImplementation": "0x62450517EfA1CE60d79801daf8f95973865e8D40", + "beaconOracle": "0x4C116BB629bff7A8373c2378bBd919f8349B8f25", + "delayedWithdrawalRouter": "0xC4BC46a87A67a531eCF7f74338E1FA79533334Fa", + "delayedWithdrawalRouterImplementation": "0x0011FA2c512063C495f77296Af8d195F33A8Dd38", + "delegationManager": "0x75dfE5B44C2E530568001400D3f704bC8AE350CC", + "delegationManagerImplementation": "0x56E88cb4f0136fC27D95499dE4BE2acf47946Fa1", + "eigenLayerPauserReg": "0x9Ab2FEAf0465f0eD51Fc2b663eF228B418c9Dad1", + "eigenLayerProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B", + "eigenPodBeacon": "0x92Cc4a800A1513E85C481dDDf3A06C6921211eaC", + "eigenPodImplementation": "0x2D6c7f9862BD80Cf0d9d93FC6b513D69E7Db7869", + "eigenPodManager": "0xB8d8952f572e67B11e43bC21250967772fa883Ff", + "eigenPodManagerImplementation": "0xc5B857A92245f64e9D90cCc5b096Db82eB77eB5c", + "emptyContract": "0x9690d52B1Ce155DB2ec5eCbF5a262ccCc7B3A6D2", + "paymentCoordinator": "0xb22Ef643e1E067c994019A4C19e403253C05c2B0", + "paymentCoordinatorImplementation": "0xC9366ab4A299e0937EC15A6C256C4481C05A24fD", + "slasher": "0x12699471dF8dca329C76D72823B1b79d55709384", + "slasherImplementation": "0x9460fCe11E1e0365419fa860599903B4E5097cf0", + "numStrategiesDeployed": 0, + "strategies": {}, + "strategyAddresses": [], + "strategyManager": "0xF9fbF2e35D8803273E214c99BF15174139f4E67a", + "strategyManagerImplementation": "0x1a26B23a004C512350d7Dd89056655A80b850199", + "token": { + "EIGEN": "0xD58f6844f79eB1fbd9f7091d05f7cb30d3363926", + "EIGENImpl": "0x95a7431400F362F3647a69535C5666cA0133CAA0", + "bEIGEN": "0xA72942289a043874249E60469F68f08B8c6ECCe8", + "bEIGENImpl": "0xd5FdabDac3d8ACeAB7BFfDDFA18877A4c5D5Aa82", + "eigenStrategy": "0xdcCF401fD121d8C542E96BC1d0078884422aFAD2", + "eigenStrategyImpl": "0x59D13E7Fb0bC0e57c1fc6594ff701592A6e4dD2B", + "tokenProxyAdmin": "0x1BEF05C7303d44e0E2FCD2A19d993eDEd4c51b5B" + } + }, + "chainInfo": { + "chainId": 17000, + "deploymentBlock": 1477016 + }, + "parameters": { + "communityMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "executorMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "operationsMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "pauserMultisig": "0xDA29BB71669f46F2a779b4b62f03644A84eE3479", + "timelock": "0xcF19CE0561052a7A7Ff21156730285997B350A7D" + } +} \ No newline at end of file