From a87c7d7734429656ec5aed2a2a3f4a3a6946b5bb Mon Sep 17 00:00:00 2001 From: Morty Date: Thu, 25 Jul 2024 01:03:20 +0800 Subject: [PATCH] feat: l1 robust deployment script --- .gitignore | 2 + scripts/deterministic/DeployScroll.s.sol | 240 +++++++++++------- .../deterministic/DeterministicDeployment.sol | 25 +- 3 files changed, 175 insertions(+), 92 deletions(-) diff --git a/.gitignore b/.gitignore index 88e59a6..ecf447b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,5 @@ broadcast # Visual Studio Code .vscode + +volume \ No newline at end of file diff --git a/scripts/deterministic/DeployScroll.s.sol b/scripts/deterministic/DeployScroll.s.sol index 197e42f..00512c3 100644 --- a/scripts/deterministic/DeployScroll.s.sol +++ b/scripts/deterministic/DeployScroll.s.sol @@ -1011,111 +1011,145 @@ contract DeployScroll is DeterminsticDeployment { **********************/ function initializeScrollChain() private { - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize( - notnull(L1_MESSAGE_QUEUE_PROXY_ADDR), - notnull(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR), - MAX_TX_IN_CHUNK - ); + if (getInitializeCount(L1_SCROLL_CHAIN_PROXY_ADDR) == 0) { + ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).initialize( + notnull(L1_MESSAGE_QUEUE_PROXY_ADDR), + notnull(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR), + MAX_TX_IN_CHUNK + ); + } - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDR); - ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDR); + if (!ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).isSequencer(L1_COMMIT_SENDER_ADDR)) { + ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addSequencer(L1_COMMIT_SENDER_ADDR); + } + if (!ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).isProver(L1_FINALIZE_SENDER_ADDR)) { + ScrollChain(L1_SCROLL_CHAIN_PROXY_ADDR).addProver(L1_FINALIZE_SENDER_ADDR); + } } function initializeL2GasPriceOracle() private { - L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize( - 21000, // _txGas - 53000, // _txGasContractCreation - 4, // _zeroGas - 16 // _nonZeroGas - ); - - L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR); + if (getInitializeCount(L2_GAS_PRICE_ORACLE_PROXY_ADDR) == 0) { + L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).initialize( + 21000, // _txGas + 53000, // _txGasContractCreation + 4, // _zeroGas + 16 // _nonZeroGas + ); + } + if (L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).whitelist() != L1_WHITELIST_ADDR) { + L2GasPriceOracle(L2_GAS_PRICE_ORACLE_PROXY_ADDR).updateWhitelist(L1_WHITELIST_ADDR); + } } function initializeL1MessageQueue() private { - L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize( - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR), - notnull(L1_SCROLL_CHAIN_PROXY_ADDR), - notnull(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR), - notnull(L2_GAS_PRICE_ORACLE_PROXY_ADDR), - MAX_L1_MESSAGE_GAS_LIMIT - ); - - L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2(); + if (getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 0) { + L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initialize( + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR), + notnull(L1_SCROLL_CHAIN_PROXY_ADDR), + notnull(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR), + notnull(L2_GAS_PRICE_ORACLE_PROXY_ADDR), + MAX_L1_MESSAGE_GAS_LIMIT + ); + } + if ( + getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 0 || getInitializeCount(L1_MESSAGE_QUEUE_PROXY_ADDR) == 1 + ) { + L1MessageQueueWithGasPriceOracle(L1_MESSAGE_QUEUE_PROXY_ADDR).initializeV2(); + } } function initializeL1ScrollMessenger() private { - L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize( - notnull(L2_SCROLL_MESSENGER_PROXY_ADDR), - notnull(L1_FEE_VAULT_ADDR), - notnull(L1_SCROLL_CHAIN_PROXY_ADDR), - notnull(L1_MESSAGE_QUEUE_PROXY_ADDR) - ); + if (getInitializeCount(L1_SCROLL_MESSENGER_PROXY_ADDR) == 0) { + L1ScrollMessenger(payable(L1_SCROLL_MESSENGER_PROXY_ADDR)).initialize( + notnull(L2_SCROLL_MESSENGER_PROXY_ADDR), + notnull(L1_FEE_VAULT_ADDR), + notnull(L1_SCROLL_CHAIN_PROXY_ADDR), + notnull(L1_MESSAGE_QUEUE_PROXY_ADDR) + ); + } } function initializeEnforcedTxGateway() private { - EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize( - notnull(L1_MESSAGE_QUEUE_PROXY_ADDR), - notnull(L1_FEE_VAULT_ADDR) - ); + if (getInitializeCount(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR) == 0) { + EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).initialize( + notnull(L1_MESSAGE_QUEUE_PROXY_ADDR), + notnull(L1_FEE_VAULT_ADDR) + ); + } // disable gateway - EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).setPause(true); + if (!EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).paused()) { + EnforcedTxGateway(payable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR)).setPause(true); + } } function initializeL1GatewayRouter() private { - L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize( - notnull(L1_ETH_GATEWAY_PROXY_ADDR), - notnull(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR) - ); + if (getInitializeCount(L1_GATEWAY_ROUTER_PROXY_ADDR) == 0) { + L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).initialize( + notnull(L1_ETH_GATEWAY_PROXY_ADDR), + notnull(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR) + ); + } } function initializeL1CustomERC20Gateway() private { - L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize( - notnull(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR), - notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) - ); + if (getInitializeCount(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR) == 0) { + L1CustomERC20Gateway(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).initialize( + notnull(L2_CUSTOM_ERC20_GATEWAY_PROXY_ADDR), + notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) + ); + } } function initializeL1ERC1155Gateway() private { - L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize( - notnull(L2_ERC1155_GATEWAY_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) - ); + if (getInitializeCount(L1_ERC1155_GATEWAY_PROXY_ADDR) == 0) { + L1ERC1155Gateway(L1_ERC1155_GATEWAY_PROXY_ADDR).initialize( + notnull(L2_ERC1155_GATEWAY_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) + ); + } } function initializeL1ERC721Gateway() private { - L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize( - notnull(L2_ERC721_GATEWAY_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) - ); + if (getInitializeCount(L1_ERC721_GATEWAY_PROXY_ADDR) == 0) { + L1ERC721Gateway(L1_ERC721_GATEWAY_PROXY_ADDR).initialize( + notnull(L2_ERC721_GATEWAY_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) + ); + } } function initializeL1ETHGateway() private { - L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize( - notnull(L2_ETH_GATEWAY_PROXY_ADDR), - notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) - ); + if (getInitializeCount(L1_ETH_GATEWAY_PROXY_ADDR) == 0) { + L1ETHGateway(L1_ETH_GATEWAY_PROXY_ADDR).initialize( + notnull(L2_ETH_GATEWAY_PROXY_ADDR), + notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) + ); + } } function initializeL1StandardERC20Gateway() private { - L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize( - notnull(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR), - notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR), - notnull(L2_SCROLL_STANDARD_ERC20_ADDR), - notnull(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR) - ); + if (getInitializeCount(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR) == 0) { + L1StandardERC20Gateway(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).initialize( + notnull(L2_STANDARD_ERC20_GATEWAY_PROXY_ADDR), + notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR), + notnull(L2_SCROLL_STANDARD_ERC20_ADDR), + notnull(L2_SCROLL_STANDARD_ERC20_FACTORY_ADDR) + ); + } } function initializeL1WETHGateway() private { - L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize( - notnull(L2_WETH_GATEWAY_PROXY_ADDR), - notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), - notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) - ); + if (getInitializeCount(L1_WETH_GATEWAY_PROXY_ADDR) == 0) { + L1WETHGateway(payable(L1_WETH_GATEWAY_PROXY_ADDR)).initialize( + notnull(L2_WETH_GATEWAY_PROXY_ADDR), + notnull(L1_GATEWAY_ROUTER_PROXY_ADDR), + notnull(L1_SCROLL_MESSENGER_PROXY_ADDR) + ); + } // set WETH gateway in router { @@ -1123,14 +1157,18 @@ contract DeployScroll is DeterminsticDeployment { _tokens[0] = notnull(L1_WETH_ADDR); address[] memory _gateways = new address[](1); _gateways[0] = notnull(L1_WETH_GATEWAY_PROXY_ADDR); - L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways); + if (L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).ERC20Gateway(_tokens[0]) != _gateways[0]) { + L1GatewayRouter(L1_GATEWAY_ROUTER_PROXY_ADDR).setERC20Gateway(_tokens, _gateways); + } } } function initializeL1Whitelist() private { address[] memory accounts = new address[](1); accounts[0] = L1_GAS_ORACLE_SENDER_ADDR; - Whitelist(L1_WHITELIST_ADDR).updateWhitelistStatus(accounts, true); + if (!Whitelist(L1_WHITELIST_ADDR).isSenderAllowed(accounts[0])) { + Whitelist(L1_WHITELIST_ADDR).updateWhitelistStatus(accounts, true); + } } function transferL1ContractOwnership() private { @@ -1138,21 +1176,51 @@ contract DeployScroll is DeterminsticDeployment { return; } - Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_PROXY_ADMIN_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(OWNER_ADDR); - Ownable(L1_WHITELIST_ADDR).transferOwnership(OWNER_ADDR); + if (Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_ENFORCED_TX_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_CUSTOM_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_ERC1155_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_ERC721_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_ETH_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_ETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_GATEWAY_ROUTER_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_MESSAGE_QUEUE_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_SCROLL_MESSENGER_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_STANDARD_ERC20_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_WETH_GATEWAY_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_WETH_GATEWAY_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L2_GAS_PRICE_ORACLE_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_MULTIPLE_VERSION_ROLLUP_VERIFIER_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_PROXY_ADMIN_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_PROXY_ADMIN_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_SCROLL_CHAIN_PROXY_ADDR).transferOwnership(OWNER_ADDR); + } + if (Ownable(L1_WHITELIST_ADDR).owner() != OWNER_ADDR) { + Ownable(L1_WHITELIST_ADDR).transferOwnership(OWNER_ADDR); + } } /********************** diff --git a/scripts/deterministic/DeterministicDeployment.sol b/scripts/deterministic/DeterministicDeployment.sol index 4bc8d11..cd3eefd 100644 --- a/scripts/deterministic/DeterministicDeployment.sol +++ b/scripts/deterministic/DeterministicDeployment.sol @@ -6,6 +6,7 @@ import {stdToml} from "forge-std/StdToml.sol"; import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; import {CONFIG_CONTRACTS_PATH, DEFAULT_DEPLOYMENT_SALT, DETERMINISTIC_DEPLOYMENT_PROXY_ADDR} from "./Constants.sol"; import {Configuration} from "./Configuration.sol"; @@ -115,7 +116,9 @@ abstract contract DeterminsticDeployment is Configuration { address proxyAddr, address implAddr ) internal { - if (!skipDeploy) { + address addr = _getImplementation(proxyAddr); + + if (!skipDeploy && addr != implAddr) { ProxyAdmin(notnull(proxyAdminAddr)).upgrade( ITransparentUpgradeableProxy(notnull(proxyAddr)), notnull(implAddr) @@ -123,11 +126,16 @@ abstract contract DeterminsticDeployment is Configuration { } } + function getInitializeCount(address contractAddr) internal view returns (uint8) { + bytes32 slotValue = vm.load(address(contractAddr), bytes32(uint256(0))); + return uint8(uint256(slotValue)); + } + /********************* * Private functions * *********************/ - function _getSalt(string memory name) internal view returns (bytes32) { + function _getSalt(string memory name) private view returns (bytes32) { return keccak256(abi.encodePacked(saltPrefix, name)); } @@ -148,11 +156,9 @@ abstract contract DeterminsticDeployment is Configuration { return addr; } - // revert if the contract is already deployed + // skip if the contract is already deployed if (addr.code.length > 0) { - revert( - string(abi.encodePacked("[ERROR] contract ", name, " (", vm.toString(addr), ") is already deployed")) - ); + return addr; } // deploy contract @@ -223,4 +229,11 @@ abstract contract DeterminsticDeployment is Configuration { } } } + + function _getImplementation(address proxyAddr) private view returns (address) { + // ERC1967Upgrade implementation slot + bytes32 _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + // get implementation address + return address(uint160(uint256(vm.load(address(proxyAddr), _IMPLEMENTATION_SLOT)))); + } }