From 44fc13016f5448acc90a7a5b6eee916fdcedace5 Mon Sep 17 00:00:00 2001 From: Kumar Satyarth <47723310+ksatyarth2@users.noreply.github.com> Date: Wed, 5 Feb 2025 13:54:40 +0530 Subject: [PATCH] feat: add script for xpufETH on apechain (#97) * feat: add script for xpufETH on apechain * forge fmt * add values to deployer helper * forge fmt --------- Co-authored-by: Benjamin Co-authored-by: bxmmm1 <28648109+bxmmm1@users.noreply.github.com> --- .../script/DeployApechainXpufETH.s.sol | 103 ++++++++++++++++++ mainnet-contracts/script/DeployerHelper.s.sol | 47 ++++++++ 2 files changed, 150 insertions(+) create mode 100644 mainnet-contracts/script/DeployApechainXpufETH.s.sol diff --git a/mainnet-contracts/script/DeployApechainXpufETH.s.sol b/mainnet-contracts/script/DeployApechainXpufETH.s.sol new file mode 100644 index 0000000..9375423 --- /dev/null +++ b/mainnet-contracts/script/DeployApechainXpufETH.s.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.8.0 <0.9.0; + +import "forge-std/Script.sol"; +import { AccessManager } from "@openzeppelin/contracts/access/manager/AccessManager.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { Multicall } from "@openzeppelin/contracts/utils/Multicall.sol"; +import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; +import { xPufETH } from "src/l2/xPufETH.sol"; +import { Timelock } from "../src/Timelock.sol"; +import { DeployerHelper } from "script/DeployerHelper.s.sol"; +import { ROLE_ID_OPERATIONS_MULTISIG, ROLE_ID_DAO, PUBLIC_ROLE } from "./Roles.sol"; + +/** + * // Check that the simulation + * add --slow if deploying to a mainnet fork like tenderly (its buggy sometimes) + * + * forge script script/DeployApechainXpufETH.s.sol:DeployApechainXpufETH --rpc-url $RPC_URL --account puffer + * + * forge cache clean + * + * forge script script/DeployApechainXpufETH.s.sol:DeployApechainXpufETH --rpc-url $RPC_URL --account puffer --broadcast + */ +contract DeployApechainXpufETH is DeployerHelper { + uint256 MINTING_LIMIT = 100 ether; + uint256 BURNING_LIMIT = 100 ether; + + Timelock timelock; + AccessManager accessManager; + + xPufETH public xPufETHProxy; + + function run() public { + vm.startBroadcast(); + + accessManager = new AccessManager(_getPufferDeployer()); + + timelock = new Timelock({ + accessManager: address(accessManager), + communityMultisig: _getCommunityMultisig(), + operationsMultisig: _getOPSMultisig(), + pauser: _getPauserMultisig(), + initialDelay: 7 days + }); + + xPufETH xpufETHImplementation = new xPufETH(); + + xPufETHProxy = xPufETH( + address( + new ERC1967Proxy{ salt: bytes32("xPufETH") }( + address(xpufETHImplementation), abi.encodeCall(xPufETH.initialize, (address(accessManager))) + ) + ) + ); + console.log("Timelock:", address(timelock)); + console.log("AccessManager:", address(accessManager)); + console.log("xpufETHProxy:", address(xPufETHProxy)); + console.log("xpufETH implementation:", address(xpufETHImplementation)); + + // setup the limits for the bridge + bytes memory setLimitsCalldata = + abi.encodeWithSelector(xPufETH.setLimits.selector, _getEverclear(), MINTING_LIMIT, BURNING_LIMIT); + + accessManager.execute(address(xPufETHProxy), setLimitsCalldata); + + // setup all access manager roles + bytes[] memory calldatas = _generateAccessManagerCallData(); + accessManager.multicall(calldatas); + } + + function _generateAccessManagerCallData() internal view returns (bytes[] memory) { + bytes[] memory calldatas = new bytes[](6); + + calldatas[0] = abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_DAO, _getOPSMultisig(), 0); + + calldatas[1] = + abi.encodeWithSelector(AccessManager.grantRole.selector, ROLE_ID_OPERATIONS_MULTISIG, _getOPSMultisig(), 0); + + bytes4[] memory daoSelectors = new bytes4[](2); + daoSelectors[0] = xPufETH.setLockbox.selector; + daoSelectors[1] = xPufETH.setLimits.selector; + + calldatas[2] = abi.encodeWithSelector( + AccessManager.setTargetFunctionRole.selector, address(xPufETHProxy), daoSelectors, ROLE_ID_DAO + ); + + bytes4[] memory publicSelectors = new bytes4[](2); + publicSelectors[0] = xPufETH.mint.selector; + publicSelectors[1] = xPufETH.burn.selector; + + calldatas[3] = abi.encodeWithSelector( + AccessManager.setTargetFunctionRole.selector, address(xPufETHProxy), publicSelectors, PUBLIC_ROLE + ); + + calldatas[4] = + abi.encodeWithSelector(AccessManager.grantRole.selector, accessManager.ADMIN_ROLE(), address(timelock), 0); + + calldatas[5] = + abi.encodeWithSelector(AccessManager.revokeRole.selector, accessManager.ADMIN_ROLE(), _getPufferDeployer()); + + return calldatas; + } +} diff --git a/mainnet-contracts/script/DeployerHelper.s.sol b/mainnet-contracts/script/DeployerHelper.s.sol index c6d57fb..4267344 100644 --- a/mainnet-contracts/script/DeployerHelper.s.sol +++ b/mainnet-contracts/script/DeployerHelper.s.sol @@ -18,6 +18,7 @@ abstract contract DeployerHelper is Script { uint256 public base = 8453; uint256 public sepolia = 11155111; uint256 public opSepolia = 11155420; + uint256 public ape = 33139; function _getDeployer() internal returns (address) { (, address msgSender,) = vm.readCallers(); @@ -25,6 +26,21 @@ abstract contract DeployerHelper is Script { return msgSender; } + function _getPufferDeployer() internal view returns (address) { + if (block.chainid == mainnet) { + // https://etherscan.io/address/0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76 + return 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76; + } else if (block.chainid == holesky) { + // https://holesky.etherscan.io/address/0xDDDeAfB492752FC64220ddB3E7C9f1d5CcCdFdF0 + return 0xDDDeAfB492752FC64220ddB3E7C9f1d5CcCdFdF0; + } else if (block.chainid == ape) { + // https://apescan.io/address/0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76 + return 0xb7d83623906AC3fa577F45B7D2b9D4BD26BC5d76; + } + + revert("PufferDeployer not available for this chain"); + } + function _getDAO() internal view returns (address) { // ATM Ops multisig is the DAO return _getOPSMultisig(); @@ -417,7 +433,11 @@ abstract contract DeployerHelper is Script { } else if (block.chainid == sepolia) { // https://sepolia.etherscan.io/address/0x445fbf9cCbaf7d557fd771d56937E94397f43965 return 0x445fbf9cCbaf7d557fd771d56937E94397f43965; + } else if (block.chainid == ape) { + // https://apescan.io/address/0xD1daF260951B8d350a4AeD5C80d74Fd7298C93F4 + return 0xD1daF260951B8d350a4AeD5C80d74Fd7298C93F4; } + revert("Everclear not available for this chain"); } @@ -433,6 +453,30 @@ abstract contract DeployerHelper is Script { revert("Paymaster not available for this chain"); } + function _getCommunityMultisig() internal view returns (address) { + if (block.chainid == mainnet) { + // https://etherscan.io/address/0x446d4d6b26815f9bA78B5D454E303315D586Cb2a + return 0x446d4d6b26815f9bA78B5D454E303315D586Cb2a; + } else if (block.chainid == ape) { + // https://apescan.io/address/0xE417FD3b116eb604De2E14715DaeB099154E597B + return 0xE417FD3b116eb604De2E14715DaeB099154E597B; + } + + revert("CommunityMultisig not available for this chain"); + } + + function _getPauserMultisig() internal view returns (address) { + if (block.chainid == mainnet) { + // https://etherscan.io/address/0x1ba8e3aA853F73ae8093E26B7B8F2520c3620Df4 + return 0x1ba8e3aA853F73ae8093E26B7B8F2520c3620Df4; + } else if (block.chainid == ape) { + // https://apescan.io/address/0x0B975bB578e9111977Bc75b667f3C18f96cD03E7 + return 0x0B975bB578e9111977Bc75b667f3C18f96cD03E7; + } + + revert("PauserMultisig not available for this chain"); + } + function _getOPSMultisig() internal view returns (address) { if (block.chainid == mainnet) { // https://etherscan.io/address/0xC0896ab1A8cae8c2C1d27d011eb955Cca955580d @@ -440,6 +484,9 @@ abstract contract DeployerHelper is Script { } else if (block.chainid == holesky) { // https://holesky.etherscan.io/address/0xDDDeAfB492752FC64220ddB3E7C9f1d5CcCdFdF0 return 0xDDDeAfB492752FC64220ddB3E7C9f1d5CcCdFdF0; + } else if (block.chainid == ape) { + // https://apescan.io/address/0x36E3881Ff855c264045c22179b6fBc01430F97EC + return 0x36E3881Ff855c264045c22179b6fBc01430F97EC; } revert("OPSMultisig not available for this chain");