From 88684d40d6262bd84fc4be892bfe10111efea684 Mon Sep 17 00:00:00 2001 From: tre Date: Tue, 5 Nov 2024 11:14:37 -0800 Subject: [PATCH] feat: refactor deployment scripts to use same script for single and multi-chain deployments (#45) --- README.md | 46 ++++--------------- package.json | 5 +- packages/contracts/README.md | 4 +- packages/contracts/configs/deploy-config.toml | 5 -- packages/contracts/package.json | 5 +- .../MultiChainSuperchainERC20Deployment.s.sol | 23 ---------- ...SingleChainSuperchainERC20Deployment.s.sol | 17 ------- ...oyer.sol => SuperchainERC20Deployer.s.sol} | 25 +++++++--- 8 files changed, 33 insertions(+), 97 deletions(-) delete mode 100644 packages/contracts/scripts/MultiChainSuperchainERC20Deployment.s.sol delete mode 100644 packages/contracts/scripts/SingleChainSuperchainERC20Deployment.s.sol rename packages/contracts/scripts/{SuperchainERC20Deployer.sol => SuperchainERC20Deployer.s.sol} (72%) diff --git a/README.md b/README.md index 57d52f1..9756c81 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,7 @@ - [Deployment config](#deployment-config) - [`[deploy-config]`](#deploy-config) - [`[token]`](#token) - - [`[single_chain_deploy_config]`](#single_chain_deploy_config) - - [`[multi_chain_deploy_config]`](#multi_chain_deploy_config) - - [Deploying to multiple chains](#deploying-to-multiple-chains) - - [Deploying to single chain](#deploying-to-single-chain) + - [Deploying a token](#deploying-a-token) - [Best practices for deploying SuperchainERC20](#best-practices-for-deploying-superchainerc20) - [Use Create2 to deploy SuperchainERC20](#use-create2-to-deploy-superchainerc20) - [`crosschainMint` and `crosschainBurn` permissions](#crosschainmint-and-crosschainburn-permissions) @@ -105,14 +102,16 @@ pnpm contracts:update:rpcs ### Deployment config -The deployment configuration for token deployments is managed through the `deploy-config.toml` file. The options available in this file allow you to customize both single and multi-chain deployments. Below is a detailed breakdown of each configuration section: +The deployment configuration for token deployments is managed through the `deploy-config.toml` file. Below is a detailed breakdown of each configuration section: #### `[deploy-config]` -This section defines parameters for deploying token contracts across both single and multi-chain environments. +This section defines parameters for deploying token contracts. - `salt`: A unique identifier used for deploying token contracts via [`Create2`]. This value along with the contract bytecode ensures that contract deployments are deterministic. - example: `salt = "ethers phoenix"` +- `chains`: Lists the chains where the token will be deployed. Each chain must correspond to an entry in the `[rpc_endpoints]` section of `foundry.toml`. + - example: `chains = ["op_chain_a","op_chain_b"]` #### `[token]` @@ -128,43 +127,16 @@ Deployment configuration for the token that will be deployed. - `decimals`: the number of decimal places the token supports. - example: `decimals = 18` -#### `[single_chain_deploy_config]` - -This section contains configuration settings specific to single chain deployments via the `SingleChainSuperchainERC20Deployment.s.sol` script. - -- `chain`: specifies the chain where the token will be deployed. This value must correspond to a chain in the `[rpc_endpoints]` section of `foundry.toml`. - - example: `chain = "op/mainnet"` - -#### `[multi_chain_deploy_config]` - -This section contains configuration settings specific to multi-chain deployments via the `MultiChainSuperchainERC20Deployment.s.sol` script. - -- `chains`: Lists the chains where the token will be deployed. Each chain must correspond to an entry in the `[rpc_endpoints]` section of `foundry.toml`. - - example: `chains = ["op_chain_a","op_chain_b"]` - -### Deploying to multiple chains - -Before proceeding with this section, ensure that your `deploy-config.toml` file is fully configured (see the [Deployment config](#deployment-config) section for more details on setup). Additionally, confirm that the `[rpc_endpoints]` section in `foundry.toml` is properly set up by following the instructions in [Configuring RPC urls](#configuring-rpc-urls). - -Multi-chain deployments are executed through the `MultiChainSuperchainERC20Deployment.s.sol` script. This script deploys tokens across each specified chain in the deployment configuration using `Create2`, ensuring deterministic contract addresses for each deployment. The script targets the `L2NativeSuperchainERC20.sol` contract by default. If you need to modify the token being deployed, either update this file directly or point the script to a custom token contract of your choice. - -To execute a multi-chain deployment run: - -```sh -pnpm contracts:deploy:multichain - -``` - -### Deploying to single chain +### Deploying a token Before proceeding with this section, ensure that your `deploy-config.toml` file is fully configured (see the [Deployment config](#deployment-config) section for more details on setup). Additionally, confirm that the `[rpc_endpoints]` section in `foundry.toml` is properly set up by following the instructions in [Configuring RPC urls](#configuring-rpc-urls). -A single chain deployment is executed through the `SingleChainSuperchainERC20Deployment.s.sol` script. This script deploys a token on the specified chain in the deployment configuration using `Create2`, ensuring deterministic contract addresses for the deployment. The script targets the `L2NativeSuperchainERC20.sol` contract by default. If you need to modify the token being deployed, either update this file directly or point the script to a custom token contract of your choice. +Deployments are executed through the `SuperchainERC20Deployer.s.sol` script. This script deploys tokens across each specified chain in the deployment configuration using `Create2`, ensuring deterministic contract addresses for each deployment. The script targets the `L2NativeSuperchainERC20.sol` contract by default. If you need to modify the token being deployed, either update this file directly or point the script to a custom token contract of your choice. -To execute a single chain deployment run: +To execute a token deployment run: ```sh -pnpm contracts:deploy:singlechain +pnpm contracts:deploy:token ``` diff --git a/package.json b/package.json index 369d963..bcaf4fa 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,11 @@ "dev": "mprocs", "install:contracts": "cd packages/contracts && forge install", "contracts:update:rpcs": "pnpm nx run @superchainerc20-starter/contracts:update:rpcs", - "contracts:deploy:multichain": "pnpm nx run @superchainerc20-starter/contracts:deploy:multichain", - "contracts:deploy:singlechain": "pnpm nx run @superchainerc20-starter/contracts:deploy:singlechain", + "contracts:deploy:token": "pnpm nx run @superchainerc20-starter/contracts:deploy:token", "update:toc": "doctoc README.md", "e2e-test": "mprocs -c mprocs-e2e-test.yaml", "init:env": "pnpm nx run-many --target=init:env", - "deploy:contracts:ci": "wait-port http://:8420/ready && cd packages/contracts && forge install && forge script scripts/MultiChainSuperchainERC20Deployment.s.sol --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + "deploy:contracts:ci": "wait-port http://:8420/ready && cd packages/contracts && forge install && forge script scripts/SuperchainERC20Deployer.s.sol --broadcast --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", "e2e-test:ci": "pnpm nx run @superchainerc20-starter/e2e-test:test" }, "license": "MIT", diff --git a/packages/contracts/README.md b/packages/contracts/README.md index 14a4eae..10b4079 100644 --- a/packages/contracts/README.md +++ b/packages/contracts/README.md @@ -42,9 +42,7 @@ This repository contains contracts and tooling for deploying and managing Superc ### scripts/ -- `MultiChainSuperchainERC20Deployment.s.sol` - Script for deploying the L2NativeSuperchainERC20 token to multiple chains in sequence, reading chain configuration from TOML. -- `SingleChainSuperchainERC20Deployment.s.sol` - Script for deploying the L2NativeSuperchainERC20 token to a single chain, reading chain configuration from TOML. -- `SuperchainERC20Deployer.sol` - Base deployment logic used by both single and multi-chain deployment scripts. +- `SuperchainERC20Deployer.s.sol` - Script for deploying the L2NativeSuperchainERC20 token to the configured chains in sequence, reading chain configuration from TOML. ## Deploying diff --git a/packages/contracts/configs/deploy-config.toml b/packages/contracts/configs/deploy-config.toml index 65b0145..2c85a34 100644 --- a/packages/contracts/configs/deploy-config.toml +++ b/packages/contracts/configs/deploy-config.toml @@ -1,10 +1,5 @@ [deploy_config] salt = "ethers phoenix" - -[single_chain_deploy_config] -chain = "op_chain_a" - -[multi_chain_deploy_config] chains = ["op_chain_a","op_chain_b"] [token] diff --git a/packages/contracts/package.json b/packages/contracts/package.json index e1bfbe1..86256e6 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,9 +1,8 @@ { "name": "@superchainerc20-starter/contracts", "scripts": { - "deploy:dev": "source .env && wait-port http://:8420/ready && forge script scripts/MultiChainSuperchainERC20Deployment.s.sol --broadcast --private-key $DEPLOYER_PRIVATE_KEY", - "deploy:multichain": "source .env && forge script scripts/MultiChainSuperchainERC20Deployment.s.sol --broadcast --private-key $DEPLOYER_PRIVATE_KEY", - "deploy:singlechain": "source .env && forge script scripts/SingleChainSuperchainERC20Deployment.s.sol --broadcast --private-key $DEPLOYER_PRIVATE_KEY", + "deploy:dev": "source .env && wait-port http://:8420/ready && forge script scripts/SuperchainERC20Deployer.s.sol --broadcast --private-key $DEPLOYER_PRIVATE_KEY", + "deploy:token": "source .env && forge script scripts/SuperchainERC20Deployer.s.sol --broadcast --private-key $DEPLOYER_PRIVATE_KEY", "update:rpcs": "cd ../.. && ./scripts/fetch-superchain-rpc-urls.sh", "install": "forge install", "build": "forge build", diff --git a/packages/contracts/scripts/MultiChainSuperchainERC20Deployment.s.sol b/packages/contracts/scripts/MultiChainSuperchainERC20Deployment.s.sol deleted file mode 100644 index 721d31a..0000000 --- a/packages/contracts/scripts/MultiChainSuperchainERC20Deployment.s.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -import {console} from "forge-std/Script.sol"; -import {Script} from "forge-std/Script.sol"; -import {SuperchainERC20Deployer} from "./SuperchainERC20Deployer.sol"; - -contract MultiChainSuperchainERC20Deployment is Script, SuperchainERC20Deployer { - function setUp() public {} - - function run() public { - string[] memory chainsToDeployTo = vm.parseTomlStringArray(deployConfig, ".multi_chain_deploy_config.chains"); - - for (uint256 i = 0; i < chainsToDeployTo.length; i++) { - string memory chainToDeployTo = chainsToDeployTo[i]; - - console.log("Deploying to chain: ", chainToDeployTo); - - vm.createSelectFork(chainToDeployTo); - deployL2NativeSuperchainERC20(); - } - } -} diff --git a/packages/contracts/scripts/SingleChainSuperchainERC20Deployment.s.sol b/packages/contracts/scripts/SingleChainSuperchainERC20Deployment.s.sol deleted file mode 100644 index 9fe24d8..0000000 --- a/packages/contracts/scripts/SingleChainSuperchainERC20Deployment.s.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -import {console} from "forge-std/Script.sol"; -import {Script} from "forge-std/Script.sol"; -import {SuperchainERC20Deployer} from "./SuperchainERC20Deployer.sol"; - -contract SingleChainSuperchainERC20Deployment is Script, SuperchainERC20Deployer { - function setUp() public {} - - function run() public { - string memory chainToDeployTo = vm.parseTomlString(deployConfig, ".single_chain_deploy_config.chain"); - console.log("Deploying to chain: ", chainToDeployTo); - vm.createSelectFork(chainToDeployTo); - deployL2NativeSuperchainERC20(); - } -} diff --git a/packages/contracts/scripts/SuperchainERC20Deployer.sol b/packages/contracts/scripts/SuperchainERC20Deployer.s.sol similarity index 72% rename from packages/contracts/scripts/SuperchainERC20Deployer.sol rename to packages/contracts/scripts/SuperchainERC20Deployer.s.sol index 1cf26c3..c992c18 100644 --- a/packages/contracts/scripts/SuperchainERC20Deployer.sol +++ b/packages/contracts/scripts/SuperchainERC20Deployer.s.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.25; -import {console} from "forge-std/Script.sol"; +import {Script, console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {L2NativeSuperchainERC20} from "../src/L2NativeSuperchainERC20.sol"; -contract SuperchainERC20Deployer { +contract SuperchainERC20Deployer is Script { string deployConfig; constructor() { @@ -20,8 +20,20 @@ contract SuperchainERC20Deployer { vm.stopBroadcast(); } - /// @notice Foundry cheatcode VM. - Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + function setUp() public {} + + function run() public { + string[] memory chainsToDeployTo = vm.parseTomlStringArray(deployConfig, ".deploy_config.chains"); + + for (uint256 i = 0; i < chainsToDeployTo.length; i++) { + string memory chainToDeployTo = chainsToDeployTo[i]; + + console.log("Deploying to chain: ", chainToDeployTo); + + vm.createSelectFork(chainToDeployTo); + deployL2NativeSuperchainERC20(); + } + } function deployL2NativeSuperchainERC20() public broadcast returns (address addr_) { address owner = vm.parseTomlAddress(deployConfig, ".token.owner_address"); @@ -29,8 +41,9 @@ contract SuperchainERC20Deployer { string memory symbol = vm.parseTomlString(deployConfig, ".token.symbol"); uint256 decimals = vm.parseTomlUint(deployConfig, ".token.decimals"); require(decimals <= type(uint8).max, "decimals exceeds uint8 range"); - bytes memory initCode = - abi.encodePacked(type(L2NativeSuperchainERC20).creationCode, abi.encode(owner, name, symbol, uint8(decimals))); + bytes memory initCode = abi.encodePacked( + type(L2NativeSuperchainERC20).creationCode, abi.encode(owner, name, symbol, uint8(decimals)) + ); address preComputedAddress = vm.computeCreate2Address(_implSalt(), keccak256(initCode)); if (preComputedAddress.code.length > 0) { console.log(