diff --git a/.env.example b/.env.example index 2ca408e..a4fc0ca 100644 --- a/.env.example +++ b/.env.example @@ -1,36 +1,31 @@ -# Wallet Configuration - +# EOA Configuration PRIVATE_KEY="YOUR_PRIVATE_KEY" MNEMONIC="YOUR_MNEMONIC" -EOA_INDEX=0 # optional (default to 0) +EOA_INDEX=0 # Optional default to 0 # Deployment Configuration - -CHAINS="ethereum,arbitrum,base,optimism,polygon" -SALT="0x0000000000000000000000000000000000000000000000000000000000000000" +SALT="" # Optional default to bytes32(0) # Etherscan Configuration - ETHERSCAN_API_KEY="YOUR_ETHERSCAN_API_KEY" # RPC Provider Configuration (using Alchemy) - RPC_API_KEY="YOUR_ALCHEMY_API_KEY" -ETHEREUM_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" +MAINNET_RPC_URL="https://eth-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" SEPOLIA_RPC_URL="https://eth-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" OPTIMISM_RPC_URL="https://opt-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" OPTIMISM_SEPOLIA_RPC_URL="https://opt-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" -BNB_RPC_URL="https://bnb-mainnet.g.alchemy.com/v2//${RPC_API_KEY}" -BNB_TESTNET_RPC_URL="https://bnb-testnet.g.alchemy.com/v2/${RPC_API_KEY}" +BSC_RPC_URL="https://bnb-mainnet.g.alchemy.com/v2//${RPC_API_KEY}" +BSC_TESTNET_RPC_URL="https://bnb-testnet.g.alchemy.com/v2/${RPC_API_KEY}" UNICHAIN_RPC_URL="https://unichain-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" UNICHAIN_SEPOLIA_RPC_URL="https://unichain-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" POLYGON_RPC_URL="https://polygon-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" -POLYGON_AMOY_RPC_URL="https://polygon-amoy.g.alchemy.com/v2/${RPC_API_KEY}" +AMOY_RPC_URL="https://polygon-amoy.g.alchemy.com/v2/${RPC_API_KEY}" BASE_RPC_URL="https://base-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" BASE_SEPOLIA_RPC_URL="https://base-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" @@ -39,32 +34,31 @@ ARBITRUM_RPC_URL="https://arb-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" ARBITRUM_SEPOLIA_RPC_URL="https://arb-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" AVALANCHE_RPC_URL="https://avax-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" -AVALANCHE_FUJI_RPC_URL="https://avax-fuji.g.alchemy.com/v2/${RPC_API_KEY}" - -SCROLL_RPC_URL="https://scroll-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" -SCROLL_SEPOLIA_RPC_URL="https://scroll-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" +FUJI_RPC_URL="https://avax-fuji.g.alchemy.com/v2/${RPC_API_KEY}" LINEA_RPC_URL="https://linea-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" LINEA_SEPOLIA_RPC_URL="https://linea-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" -# RPC Provider Configuration (using Infura) +SCROLL_RPC_URL="https://scroll-mainnet.g.alchemy.com/v2/${RPC_API_KEY}" +SCROLL_SEPOLIA_RPC_URL="https://scroll-sepolia.g.alchemy.com/v2/${RPC_API_KEY}" +# RPC Provider Configuration (using Infura) RPC_API_KEY="YOUR_INFURA_API_KEY" -ETHEREUM_RPC_URL="https://mainnet.infura.io/v3/${RPC_API_KEY}" +MAINNET_RPC_URL="https://mainnet.infura.io/v3/${RPC_API_KEY}" SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/${RPC_API_KEY}" OPTIMISM_RPC_URL="https://optimism-mainnet.infura.io/v3/${RPC_API_KEY}" OPTIMISM_SEPOLIA_RPC_URL="https://optimism-sepolia.infura.io/v3/${RPC_API_KEY}" -BNB_RPC_URL="https://bsc-mainnet.infura.io/v3/${RPC_API_KEY}" -BNB_TESTNET_RPC_URL="https://bsc-testnet.infura.io/v3/${RPC_API_KEY}" +BSC_RPC_URL="https://bsc-mainnet.infura.io/v3/${RPC_API_KEY}" +BSC_TESTNET_RPC_URL="https://bsc-testnet.infura.io/v3/${RPC_API_KEY}" UNICHAIN_RPC_URL="https://unichain-mainnet.infura.io/v3/${RPC_API_KEY}" UNICHAIN_SEPOLIA_RPC_URL="https://unichain-sepolia.infura.io/v3/${RPC_API_KEY}" POLYGON_RPC_URL="https://polygon-mainnet.infura.io/v3/${RPC_API_KEY}" -POLYGON_AMOY_RPC_URL="https://polygon-amoy.infura.io/v3/${RPC_API_KEY}" +AMOY_RPC_URL="https://polygon-amoy.infura.io/v3/${RPC_API_KEY}" BASE_RPC_URL="https://base-mainnet.infura.io/v3/${RPC_API_KEY}" BASE_SEPOLIA_RPC_URL="https://base-sepolia.infura.io/v3/${RPC_API_KEY}" @@ -73,10 +67,10 @@ ARBITRUM_RPC_URL="https://arbitrum-mainnet.infura.io/v3/${RPC_API_KEY}" ARBITRUM_SEPOLIA_RPC_URL="https://arbitrum-sepolia.infura.io/v3/${RPC_API_KEY}" AVALANCHE_RPC_URL="https://avalanche-mainnet.infura.io/v3/${RPC_API_KEY}" -AVALANCHE_FUJI_RPC_URL="https://avalanche-fuji.infura.io/v3/${RPC_API_KEY}" - -SCROLL_RPC_URL="https://scroll-mainnet.infura.io/v3/${RPC_API_KEY}" -SCROLL_SEPOLIA_RPC_URL="https://scroll-sepolia.infura.io/v3/${RPC_API_KEY}" +FUJI_RPC_URL="https://avalanche-fuji.infura.io/v3/${RPC_API_KEY}" LINEA_RPC_URL="https://linea-mainnet.infura.io/v3/${RPC_API_KEY}" LINEA_SEPOLIA_RPC_URL="https://linea-sepolia.infura.io/v3/${RPC_API_KEY}" + +SCROLL_RPC_URL="https://scroll-mainnet.infura.io/v3/${RPC_API_KEY}" +SCROLL_SEPOLIA_RPC_URL="https://scroll-sepolia.infura.io/v3/${RPC_API_KEY}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3f17590..e7f8fcf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,17 +36,17 @@ jobs: - name: Run Forge tests env: - ETHEREUM_RPC_URL: ${{ secrets.ETHEREUM_RPC_URL }} + MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} OPTIMISM_RPC_URL: ${{ secrets.OPTIMISM_RPC_URL }} - BNB_RPC_URL: ${{ secrets.BNB_RPC_URL }} + BSC_RPC_URL: ${{ secrets.BSC_RPC_URL }} UNICHAIN_RPC_URL: ${{ secrets.UNICHAIN_RPC_URL }} POLYGON_RPC_URL: ${{ secrets.POLYGON_RPC_URL }} FANTOM_RPC_URL: ${{ secrets.FANTOM_RPC_URL }} BASE_RPC_URL: ${{ secrets.BASE_RPC_URL }} ARBITRUM_RPC_URL: ${{ secrets.ARBITRUM_RPC_URL }} AVALANCHE_RPC_URL: ${{ secrets.AVALANCHE_RPC_URL }} - SCROLL_RPC_URL: ${{ secrets.SCROLL_RPC_URL }} LINEA_RPC_URL: ${{ secrets.LINEA_RPC_URL }} + SCROLL_RPC_URL: ${{ secrets.SCROLL_RPC_URL }} run: | forge test -vvv id: test diff --git a/.prettierignore b/.prettierignore index 2e78fca..5fd1fb1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,4 @@ .github/ -foundry.toml -out/ +cache/ lib/ -cache/ \ No newline at end of file +out/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 68c2c17..028a1d4 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -12,7 +12,7 @@ } }, { - "files": "*.json", + "files": ["*.json", "*.js", "*.ts"], "options": { "useTabs": true, "bracketSpacing": true diff --git a/README.md b/README.md index 39f8950..543e922 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ forge test --gas-report ### Deploy ```bash -forge script script/Deploy.s.sol \ +forge script script/Deploy.s.sol:DeployScript \ --broadcast \ --multi \ --slow \ diff --git a/config/deployments.toml b/config/deployments.toml new file mode 100644 index 0000000..4fe9ebc --- /dev/null +++ b/config/deployments.toml @@ -0,0 +1,119 @@ +[mainnet] +endpoint_url = "${MAINNET_RPC_URL}" + +[mainnet.bool] +is_testnet = false + +[sepolia] +endpoint_url = "${SEPOLIA_RPC_URL}" + +[sepolia.bool] +is_testnet = true + +[optimism] +endpoint_url = "${OPTIMISM_RPC_URL}" + +[optimism.bool] +is_testnet = false + +[optimism-sepolia] +endpoint_url = "${OPTIMISM_SEPOLIA_RPC_URL}" + +[optimism-sepolia.bool] +is_testnet = true + +[bsc] +endpoint_url = "${BSC_RPC_URL}" + +[bsc.bool] +is_testnet = false + +[bsc-testnet] +endpoint_url = "${BSC_TESTNET_RPC_URL}" + +[bsc-testnet.bool] +is_testnet = true + +[unichain] +endpoint_url = "${UNICHAIN_RPC_URL}" + +[unichain.bool] +is_testnet = false + +[unichain-sepolia] +endpoint_url = "${UNICHAIN_SEPOLIA_RPC_URL}" + +[unichain-sepolia.bool] +is_testnet = true + +[polygon] +endpoint_url = "${POLYGON_RPC_URL}" + +[polygon.bool] +is_testnet = false + +[amoy] +endpoint_url = "${AMOY_RPC_URL}" + +[amoy.bool] +is_testnet = true + +[base] +endpoint_url = "${BASE_RPC_URL}" + +[base.bool] +is_testnet = false + +[base-sepolia] +endpoint_url = "${BASE_SEPOLIA_RPC_URL}" + +[base-sepolia.bool] +is_testnet = true + +[arbitrum] +endpoint_url = "${ARBITRUM_RPC_URL}" + +[arbitrum.bool] +is_testnet = false + +[arbitrum-sepolia] +endpoint_url = "${ARBITRUM_SEPOLIA_RPC_URL}" + +[arbitrum-sepolia.bool] +is_testnet = true + +[avalanche] +endpoint_url = "${AVALANCHE_RPC_URL}" + +[avalanche.bool] +is_testnet = false + +[fuji] +endpoint_url = "${FUJI_RPC_URL}" + +[fuji.bool] +is_testnet = true + +[linea] +endpoint_url = "${LINEA_RPC_URL}" + +[linea.bool] +is_testnet = false + +[linea-sepolia] +endpoint_url = "${LINEA_SEPOLIA_RPC_URL}" + +[linea-sepolia.bool] +is_testnet = true + +[scroll] +endpoint_url = "${SCROLL_RPC_URL}" + +[scroll.bool] +is_testnet = false + +[scroll-sepolia] +endpoint_url = "${SCROLL_SEPOLIA_RPC_URL}" + +[scroll-sepolia.bool] +is_testnet = true \ No newline at end of file diff --git a/config/test.toml b/config/test.toml new file mode 100644 index 0000000..5560798 --- /dev/null +++ b/config/test.toml @@ -0,0 +1,29 @@ +[mainnet] +endpoint_url = "${MAINNET_RPC_URL}" + +[optimism] +endpoint_url = "${OPTIMISM_RPC_URL}" + +[bsc] +endpoint_url = "${BSC_RPC_URL}" + +[unichain] +endpoint_url = "${UNICHAIN_RPC_URL}" + +[polygon] +endpoint_url = "${POLYGON_RPC_URL}" + +[base] +endpoint_url = "${BASE_RPC_URL}" + +[arbitrum] +endpoint_url = "${ARBITRUM_RPC_URL}" + +[avalanche] +endpoint_url = "${AVALANCHE_RPC_URL}" + +[linea] +endpoint_url = "${LINEA_RPC_URL}" + +[scroll] +endpoint_url = "${SCROLL_RPC_URL}" diff --git a/foundry.lock b/foundry.lock new file mode 100644 index 0000000..fee8a95 --- /dev/null +++ b/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/forge-std": { + "tag": { + "name": "v1.11.0", + "rev": "8e40513d678f392f398620b3ef2b418648b33e89" + } + } +} \ No newline at end of file diff --git a/foundry.toml b/foundry.toml index 05af6cc..62bcf88 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,4 +1,9 @@ [profile.default] +src = "src" +test = "test" +script = "script" +out = "out" +libs = ["lib"] solc = "0.8.30" evm_version = "cancun" allow_internal_expect_revert = true @@ -6,19 +11,17 @@ bytecode_hash = "none" cbor_metadata = false dynamic_test_linking = true ffi = true +fs_permissions = [{ access = "read-write", path = "./" }] optimizer = true optimizer_runs = 44444444 +verbosity = 2 via_ir = true -fs_permissions = [ - { access = "read-write", path = "./deployments" }, - { access = "read", path = "./out" }, - { access = "read", path = "./script" }, - { access = "read", path = "./test" } -] - gas_reports = ["CreateXFactory"] +[fuzz] +runs = 5000 + [fmt] line_length = 120 tab_width = 4 @@ -27,56 +30,51 @@ func_attrs_with_params_multiline = true inline_attribute_style = "compact" return_statement = "inline" -[fuzz] -runs = 5000 -max_test_rejects = 1000000 +[lint] +lint_on_build = false [rpc_endpoints] -ethereum = "${ETHEREUM_RPC_URL}" +mainnet = "${MAINNET_RPC_URL}" sepolia = "${SEPOLIA_RPC_URL}" optimism = "${OPTIMISM_RPC_URL}" optimism-sepolia = "${OPTIMISM_SEPOLIA_RPC_URL}" -bnb = "${BNB_RPC_URL}" -bnb-testnet = "${BNB_TESTNET_RPC_URL}" +bsc = "${BSC_RPC_URL}" +bsc-testnet = "${BSC_TESTNET_RPC_URL}" unichain = "${UNICHAIN_RPC_URL}" unichain-sepolia = "${UNICHAIN_SEPOLIA_RPC_URL}" polygon = "${POLYGON_RPC_URL}" -polygon-amoy = "${POLYGON_AMOY_RPC_URL}" -fantom = "${FANTOM_RPC_URL}" -fantom-testnet = "${FANTOM_TESTNET_RPC_URL}" +amoy = "${AMOY_RPC_URL}" base = "${BASE_RPC_URL}" base-sepolia = "${BASE_SEPOLIA_RPC_URL}" arbitrum = "${ARBITRUM_RPC_URL}" arbitrum-sepolia = "${ARBITRUM_SEPOLIA_RPC_URL}" avalanche = "${AVALANCHE_RPC_URL}" -avalanche-fuji = "${AVALANCHE_FUJI_RPC_URL}" -scroll = "${SCROLL_RPC_URL}" -scroll-sepolia = "${SCROLL_SEPOLIA_RPC_URL}" +fuji = "${FUJI_RPC_URL}" linea = "${LINEA_RPC_URL}" linea-sepolia = "${LINEA_SEPOLIA_RPC_URL}" +scroll = "${SCROLL_RPC_URL}" +scroll-sepolia = "${SCROLL_SEPOLIA_RPC_URL}" [etherscan] -ethereum = { key = "${ETHERSCAN_API_KEY}", chainId = 1 } +mainnet = { key = "${ETHERSCAN_API_KEY}", chainId = 1 } sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 11155111 } optimism = { key = "${ETHERSCAN_API_KEY}", chainId = 10 } optimism-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 11155420 } -bnb = { key = "${ETHERSCAN_API_KEY}", chainId = 56 } -bnb-testnet = { key = "${ETHERSCAN_API_KEY}", chainId = 97 } +bsc = { key = "${ETHERSCAN_API_KEY}", chainId = 56 } +bsc-testnet = { key = "${ETHERSCAN_API_KEY}", chainId = 97 } unichain = { key = "${ETHERSCAN_API_KEY}", chainId = 130 } unichain-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 1301 } polygon = { key = "${ETHERSCAN_API_KEY}", chainId = 137 } -polygon-amoy = { key = "${ETHERSCAN_API_KEY}", chainId = 80002 } -fantom = { key = "${ETHERSCAN_API_KEY}", chainId = 250 } -fantom-testnet = { key = "${ETHERSCAN_API_KEY}", chainId = 4002 } +amoy = { key = "${ETHERSCAN_API_KEY}", chainId = 80002 } base = { key = "${ETHERSCAN_API_KEY}", chainId = 8453 } base-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 84532 } arbitrum = { key = "${ETHERSCAN_API_KEY}", chainId = 42161 } arbitrum-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 421614 } avalanche = { key = "${ETHERSCAN_API_KEY}", chainId = 43114 } -avalanche-fuji = { key = "${ETHERSCAN_API_KEY}", chainId = 43113 } -scroll = { key = "${ETHERSCAN_API_KEY}", chainId = 534352 } -scroll-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 534351 } +fuji = { key = "${ETHERSCAN_API_KEY}", chainId = 43113 } linea = { key = "${ETHERSCAN_API_KEY}", chainId = 59144 } linea-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 59141 } +scroll = { key = "${ETHERSCAN_API_KEY}", chainId = 534352 } +scroll-sepolia = { key = "${ETHERSCAN_API_KEY}", chainId = 534351 } # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/lib/forge-std b/lib/forge-std index 77041d2..8e40513 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 77041d2ce690e692d6e03cc812b57d1ddaa4d505 +Subproject commit 8e40513d678f392f398620b3ef2b418648b33e89 diff --git a/script/BaseScript.sol b/script/BaseScript.sol index 67215bd..5689b13 100644 --- a/script/BaseScript.sol +++ b/script/BaseScript.sol @@ -1,17 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.30; -import {Script, console2 as console, stdJson} from "forge-std/Script.sol"; -import {ICreateXFactory} from "src/ICreateXFactory.sol"; -import {VmSafe} from "forge-std/Vm.sol"; +import {Script} from "forge-std/Script.sol"; +import {Config} from "forge-std/Config.sol"; +import {stdJson} from "forge-std/StdJson.sol"; -abstract contract BaseScript is Script { +abstract contract BaseScript is Script, Config { using stdJson for string; string private constant DEFAULT_MNEMONIC = "test test test test test test test test test test test junk"; - string private constant DEFAULT_CHAINS = "ethereum, optimism, polygon, base, arbitrum"; - address internal broadcaster; modifier broadcast() { @@ -20,17 +18,18 @@ abstract contract BaseScript is Script { vm.stopBroadcast(); } - modifier fork(string memory chainAlias) { - vm.createSelectFork(chainAlias); + modifier fork(uint256 chainId) { + vm.selectFork(forkOf[chainId]); _; } function setUp() public virtual { + _loadConfigAndForks("./config/deployments.toml", true); broadcaster = vm.rememberKey(configurePrivateKey()); } function configurePrivateKey() internal view virtual returns (uint256 privateKey) { - privateKey = vm.envOr({ + return vm.envOr({ name: "PRIVATE_KEY", defaultValue: vm.deriveKey({ mnemonic: vm.envOr({name: "MNEMONIC", defaultValue: DEFAULT_MNEMONIC}), @@ -41,28 +40,24 @@ abstract contract BaseScript is Script { function generateJson(string memory path, string memory name, address instance, bytes32 salt) internal virtual { string memory json = "json"; + json.serialize("name", name); json.serialize("address", instance); + json.serialize("salt", salt); json.serialize("blockNumber", vm.getBlockNumber()); json.serialize("timestamp", vm.getBlockTimestamp()); - json.serialize("salt", salt); - json = json.serialize("name", name); + json = json.serialize("deployer", broadcaster); json.write(path); } - function promptChains() internal virtual returns (string[] memory chainAliases) { - string memory input = prompt("Chains separated by ','", defaultChains()); - return vm.split(vm.replace(input, " ", ""), ","); + function prompt(string memory promptText, string memory defaultValue) internal returns (string memory input) { + input = vm.prompt(string.concat(promptText, " (default: `", defaultValue, "`)")); + if (bytes(input).length == 0) input = defaultValue; } function prompt(string memory promptText) internal returns (string memory input) { return prompt(promptText, new string(0)); } - function prompt(string memory promptText, string memory defaultValue) internal returns (string memory input) { - input = vm.prompt(string.concat(promptText, " (default: `", defaultValue, "`)")); - if (bytes(input).length == 0) input = defaultValue; - } - function promptAddress(string memory promptText, address defaultValue) internal returns (address) { return vm.parseAddress(prompt(promptText, vm.toString(defaultValue))); } @@ -110,12 +105,4 @@ abstract contract BaseScript is Script { function promptBytes(string memory promptText) internal returns (bytes memory) { return promptBytes(promptText, new bytes(0)); } - - function defaultChains() internal view virtual returns (string memory chains) { - return DEFAULT_CHAINS; - } - - function defaultSalt() internal view virtual returns (bytes32) { - return bytes32(0); - } } diff --git a/script/CreateX.s.sol b/script/CreateX.s.sol index 27f2233..93a07d4 100644 --- a/script/CreateX.s.sol +++ b/script/CreateX.s.sol @@ -2,49 +2,56 @@ pragma solidity ^0.8.30; import {ICreateXFactory} from "src/ICreateXFactory.sol"; -import {CreateX as CreateXLib} from "src/CreateX.sol"; +import {CreateX} from "src/CreateX.sol"; import {BaseScript} from "./BaseScript.sol"; import {ERC1967_PROXY_BYTECODE, TRANSPARENT_PROXY_BYTECODE} from "./Precompiles.sol"; -contract CreateX is BaseScript { +contract CreateXScript is BaseScript { + error UnsupportedChain(uint256 chainId); + ICreateXFactory internal constant CREATEX_FACTORY = ICreateXFactory(0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf); - function deployContract() internal virtual broadcast returns (address) { - uint256 creationType = promptCreationType(); - bytes memory initCode; - bytes32 salt; - uint256 value; + function setUp() public virtual override { + super.setUp(); + if (address(CREATEX_FACTORY).code.length == 0) revert UnsupportedChain(vm.getChainId()); + } + + function deployContract() internal virtual returns (address) { + ICreateXFactory.CreationType creationType = promptCreationType(); - if (creationType < uint8(ICreateXFactory.CreationType.Clone)) { - bytes memory creationCode = vm.getCode(prompt("Artifact path")); + bytes memory initCode; + if (creationType < ICreateXFactory.CreationType.Clone) { + bytes memory bytecode = vm.getCode(prompt("Artifact path")); bytes memory arguments = promptBytes("Constructor arguments"); - initCode = bytes.concat(creationCode, arguments); + initCode = bytes.concat(bytecode, arguments); } else { address implementation = vm.promptAddress("Implementation"); initCode = abi.encodePacked(implementation); } - if ( - creationType != uint8(ICreateXFactory.CreationType.CREATE) - && creationType != uint8(ICreateXFactory.CreationType.Clone) - ) { - salt = promptBytes32("Salt", defaultSalt()); + bytes32 salt; + if (creationType != ICreateXFactory.CreationType.CREATE && creationType != ICreateXFactory.CreationType.Clone) { + salt = promptBytes32("Salt", bytes32(0)); } - value = promptUint256("msg.value"); - + uint256 value = promptUint256("msg.value"); return deployCreateX(creationType, initCode, salt, value); } - function deployCreateX(uint256 creationType, bytes memory initCode, bytes32 salt) internal returns (address) { - return deployCreateX(creationType, initCode, salt, 0); - } - - function deployCreateX(uint256 creationType, bytes memory initCode, bytes32 salt, uint256 value) + function deployCreateX(ICreateXFactory.CreationType creationType, bytes memory initCode, bytes32 salt) internal returns (address) { - return CREATEX_FACTORY.createX{value: value}(asCreationType(creationType), initCode, salt); + return deployCreateX(creationType, initCode, salt, 0); + } + + function deployCreateX( + ICreateXFactory.CreationType creationType, + bytes memory initCode, + bytes32 salt, + uint256 value + ) internal returns (address) { + return CREATEX_FACTORY.createX{value: value}(creationType, initCode, salt); } function deployCreate(bytes memory initCode) internal returns (address) { @@ -107,11 +114,11 @@ contract CreateX is BaseScript { function deployTransparentProxy(address owner, address implementation, bytes memory data, uint256 value) internal - returns (address proxy, address proxyAdmin) + returns (address proxy) { bytes memory arguments = abi.encode(owner, implementation, data); bytes memory initCode = bytes.concat(TRANSPARENT_PROXY_BYTECODE, arguments); - proxyAdmin = CreateXLib.computeCreateAddress(proxy = deployCreate(initCode, value), 1); + return deployCreate(initCode, value); } function deployTransparentProxy( @@ -120,15 +127,15 @@ contract CreateX is BaseScript { bytes memory data, bytes32 salt, uint256 value - ) internal returns (address proxy, address proxyAdmin) { + ) internal returns (address proxy) { bytes memory arguments = abi.encode(owner, implementation, data); bytes memory initCode = bytes.concat(TRANSPARENT_PROXY_BYTECODE, arguments); - proxyAdmin = CreateXLib.computeCreateAddress(proxy = deployCreate2(initCode, salt, value), 1); + return deployCreate2(initCode, salt, value); } - function promptCreationType() internal returns (uint256) { + function promptCreationType() internal returns (ICreateXFactory.CreationType) { string memory promptText = "CreationType (0: CREATE, 1: CREATE2, 2: CREATE3, 3: Clone, 4: CloneDeterministic)"; - return vm.promptUint(promptText); + return asCreationType(vm.promptUint(promptText)); } function asCreationType(uint256 creationType) internal pure returns (ICreateXFactory.CreationType) { diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index 0ae7db3..81fae8d 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -4,23 +4,33 @@ pragma solidity ^0.8.30; import {CreateXFactory} from "src/CreateXFactory.sol"; import {BaseScript} from "./BaseScript.sol"; -contract Deploy is BaseScript { +contract DeployScript is BaseScript { bytes32 internal salt; function setUp() public virtual override { super.setUp(); - salt = vm.envOr({name: "SALT", defaultValue: defaultSalt()}); + salt = vm.envOr({name: "SALT", defaultValue: bytes32(0)}); + } + + function run(uint256 chainId) external { + deployToChain(chainId); + } + + function run(uint256[] memory chains) external { + for (uint256 i = 0; i < chains.length; ++i) { + deployToChain(chains[i]); + } } function run() external { - string[] memory chainAliases = promptChains(); - for (uint256 i; i < chainAliases.length; ++i) { - deployOnChain(chainAliases[i]); + uint256[] memory chains = config.getChainIds(); + for (uint256 i = 0; i < chains.length; ++i) { + deployToChain(chains[i]); } } - function deployOnChain(string memory chainAlias) internal fork(chainAlias) broadcast { - string memory path = string.concat(vm.projectRoot(), "/deployments/", vm.toString(block.chainid), ".json"); + function deployToChain(uint256 chainId) internal fork(chainId) broadcast { + string memory path = string.concat(vm.projectRoot(), "/deployments/", vm.toString(chainId), ".json"); generateJson(path, "CreateXFactory", address(new CreateXFactory{salt: salt}()), salt); } } diff --git a/script/Precompiles.sol b/script/Precompiles.sol index 8c36515..5e831e8 100644 --- a/script/Precompiles.sol +++ b/script/Precompiles.sol @@ -1,9 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.30; -bytes constant CREATEX_FACTORY_BYTECODE = - hex"60808060405234601557610aaa908161001a8239f35b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806312b40d531461031b57806328ddd046146102de578063315c8d9c146102785780636cec25361461023b5780638124b78e146101ff578063890c283b146101bf5780638c0b8db2146101ab578063a7b62a7f14610197578063b86b2ceb14610157578063cf5ba53f146101025763df6a602c14610092575f80fd5b346100fe5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760043560058110156100fe576100e060209160443590602435906108ee565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b5f80fd5b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760043567ffffffffffffffff81116100fe576100e061015160209236906004016103d7565b90610888565b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e061018e6103b4565b602435906107d5565b60206100e06101a536610405565b9161071a565b60206100e06101b936610405565b916105f4565b346100fe5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e060243560043530610a8e565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e06102366103b4565b61052b565b346100fe5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e060043530610a3e565b60607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760043560058110156100fe5760243567ffffffffffffffff81116100fe576020916102d46100e09236906004016103d7565b9060443592610456565b346100fe5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e0600435306109b4565b346100fe5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fe5760206100e06103576103b4565b60243590309160439160559360405192605884015260388301526f5af43d82803e903d91602b57fd5bf3ff60248301526014820152733d602d80600a3d3981f3363d3d373d3d3d363d7381526037600c8201206078820152012090565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036100fe57565b9181601f840112156100fe5782359167ffffffffffffffff83116100fe57602083818601950101116100fe57565b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8201126100fe576004359067ffffffffffffffff82116100fe5761044e916004016103d7565b909160243590565b92909260058110156104fe578061047557505061047291610888565b90565b9091906001810361048a5750610472926105f4565b6002810361049c57506104729261071a565b600381036104bb575090506014116100fe57610472903560601c61052b565b6004036104d6576014116100fe57610472913560601c6107d5565b7f5fc1076a000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b803b158160601b15176105e7573447106105da5780763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff6e5af43d82803e903d91602b57fd5bf39360881c16175f5260781b176020526037600934f090813b158260601b15176105cd573373ffffffffffffffffffffffffffffffffffffffff83167fb6c9f70724e4ce6b9bca2eace320dd3164063f0a0b229f8c4705ef05be829c255f80a3565b63a28c24735f526004601cfd5b63f4d678b85f526004601cfd5b6368155f9a5f526004601cfd5b8260601c3381149015171561066b5761060e913691610678565b3447106105da578051829160200134f590813b158260601b15176105cd573373ffffffffffffffffffffffffffffffffffffffff83167f09005d6d86a7a6ccbee89763e10463ab645e06615f10a6a2fe604a62f31843ef5f80a490565b6381e69d9b5f526004601cfd5b92919267ffffffffffffffff82116106ed57604051917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81601f8401160116830183811067ffffffffffffffff8211176106ed576040528294818452818301116100fe578281602093845f960137010152565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b8260601c3381149015171561066b57610734913691610678565b903447106105da576f67363d3d37363d34f03d5260086018f35f52806010805ff58060601b156107c857805f9160145261d694825260016034536017601e209338916020825192019034905af1823b02156105cd573373ffffffffffffffffffffffffffffffffffffffff83167f09005d6d86a7a6ccbee89763e10463ab645e06615f10a6a2fe604a62f31843ef5f80a490565b63d49e7d745f526004601cfd5b8160601c3381149015171561066b57803b158160601b15176105e7573447106105da5780763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff6e5af43d82803e903d91602b57fd5bf39360881c16175f5260781b17602052806037600934f590813b158260601b15176105cd573373ffffffffffffffffffffffffffffffffffffffff83167f09005d6d86a7a6ccbee89763e10463ab645e06615f10a6a2fe604a62f31843ef5f80a490565b610893913691610678565b3447106105da5760208151910134f090813b158260601b15176105cd573373ffffffffffffffffffffffffffffffffffffffff83167fb6c9f70724e4ce6b9bca2eace320dd3164063f0a0b229f8c4705ef05be829c255f80a3565b9190916005811015806104fe57811580156109a8575b156109165750506104729150306109b4565b6104fe576001810361092d57506104729130610a8e565b600281036109415750610472915030610a3e565b6004036104d6576104729160601c309160439160559360405192605884015260388301526f5af43d82803e903d91602b57fd5bf3ff60248301526014820152733d602d80600a3d3981f3363d3d373d3d3d363d7381526037600c8201206078820152012090565b50505f60038214610904565b67ffffffffffffffff821015610a3157609460015360601b6002525f9060808110610a16579081825b610a045760179250816080016016538160031b610100031b82525b8060d6015f53015f2090565b9060019260081c9283910191906109dd565b908160179215610a29575b6016536109f8565b506080610a21565b63756688fe5f526004601cfd5b90604051915f5260ff600b536020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b2060145260405261d6945f5260016034536017601e2090565b9060ff5f5360355260601b60015260155260555f20905f60355256"; - bytes constant ERC1967_PROXY_BYTECODE = hex"60806040526102728038038061001481610168565b92833981016040828203126101645781516001600160a01b03811692909190838303610164576020810151906001600160401b03821161016457019281601f8501121561016457835161006e610069826101a1565b610168565b9481865260208601936020838301011161016457815f926020809301865e86010152823b15610152577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a282511561013a575f8091610122945190845af43d15610132573d91610113610069846101a1565b9283523d5f602085013e6101bc565b505b6040516057908161021b8239f35b6060916101bc565b50505034156101245763b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f5260045260245ffd5b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761018d57604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161018d57601f01601f191660200190565b906101e057508051156101d157805190602001fd5b63d6bda27560e01b5f5260045ffd5b81511580610211575b6101f1575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156101e956fe60806040525f8073ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416368280378136915af43d5f803e156053573d5ff35b3d5ffd"; @@ -12,12 +9,3 @@ bytes constant TRANSPARENT_PROXY_BYTECODE = bytes constant PROXY_ADMIN_BYTECODE = hex"60803460b857601f6105fd38819003918201601f19168301916001600160401b0383118484101760bc5780849260209460405283398101031260b857516001600160a01b0381169081900360b857801560a5575f80546001600160a01b031981168317825560405192916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a361052c90816100d18239f35b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040526004361015610011575f80fd5b5f5f3560e01c8063715018a6146103c25780638da5cb5b146103725780639623609d146101c9578063ad3cb1cc146101465763f2fde38b14610051575f80fd5b346101435760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101435760043573ffffffffffffffffffffffffffffffffffffffff8116809103610141576100a96104e0565b80156101155773ffffffffffffffffffffffffffffffffffffffff8254827fffffffffffffffffffffffff00000000000000000000000000000000000000008216178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b6024827f1e4fbdf700000000000000000000000000000000000000000000000000000000815280600452fd5b505b80fd5b503461014357807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014357506101c560405161018760408261045c565b600581527f352e302e30000000000000000000000000000000000000000000000000000000602082015260405191829160208352602083019061049d565b0390f35b5060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103415760043573ffffffffffffffffffffffffffffffffffffffff81168091036103415760243573ffffffffffffffffffffffffffffffffffffffff81168091036103415760443567ffffffffffffffff8111610341573660238201121561034157806004013567ffffffffffffffff8111610345576040519161029d601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0166020018461045c565b818352366024838301011161034157815f9260246020930183860137830101526102c56104e0565b823b1561034157610314925f926040518095819482937f4f1ef286000000000000000000000000000000000000000000000000000000008452600484015260406024840152604483019061049d565b039134905af1801561033657610328575080f35b61033491505f9061045c565b005b6040513d5f823e3d90fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b34610341575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261034157602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b34610341575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610341576103f86104e0565b5f73ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761034557604052565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b73ffffffffffffffffffffffffffffffffffffffff5f5416330361050057565b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd"; - -bytes constant FORGE_PROXY_BYTECODE = - hex"60a0806040526106a28038038091610017828561023a565b83398101906060818303126102225761002f8161025d565b9161003c6020830161025d565b604083015190926001600160401b038211610222570181601f820112156102225780516001600160401b0381116102265760405191610085601f8301601f19166020018461023a565b81835260208301936020838301011161022257815f926020809301865e83010152604051936101206102f86100bd602082018861023a565b80875260208701906103aa8239604080516001600160a01b039097166020888101918252808952916100ef908961023a565b6040519788938385019a5180918c5e840190838201905f8252519283915e01015f815203601f19810186528561023a565b803b1561021557807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a28151156101ff575f92839251915af4156101f7575b51905ff08060601b156101f757807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355806020527f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f60405fa1608052604051610138908161027282396080518160070152f35b3d5f803e3d5ffd5b505050341561018457636fb1b0e95f526004601cfd5b6368155f9a5f526004601cfd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b601f909101601f19168101906001600160401b0382119082101761022657604052565b51906001600160a01b03821682036102225756fe6080604052337f00000000000000000000000000000000000000000000000000000000000000001460011461006b57365f80375f8036817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d5f803e15610067573d5ff35b3d5ffd5b634f1ef2865f3560e01c0361012b5773ffffffffffffffffffffffffffffffffffffffff60043516803b1561011e57807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a260443590811561010857815f8093928193606483375af41561010057005b3d5f803e3d5ffd5b50503461011157005b636fb1b0e95f526004601cfd5b6368155f9a5f526004601cfd5b63d2b576ec5f526004601cfd60803460b757601f6102f838819003918201601f19168301916001600160401b0383118484101760bb5780849260209460405283398101031260b757516001600160a01b038116810360b7578060601b1560aa57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a360405161022890816100d08239f35b6354a567865f526004601cfd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6004361061021b575f3560e01c8080638da5cb5b146101f25763ad3cb1cc146101c057337f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd554036101af5780639623609d146101295763f2fde38b1461006c57637352d91c5f526004601cfd5b6004357fffffffffffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff82169160601b161561011c57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a37f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd555005b6354a567865f526004601cfd5b50634f1ef2865f527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016024602037604080525f807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601601c3473ffffffffffffffffffffffffffffffffffffffff600435165af1156101a757005b3d5f803e3d5ffd5b6332b2baa35f52336020526024601cfd5b60205f5260056020527f352e302e3000000000000000000000000000000000000000000000000000000060405260605ff35b7f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5545f5260205ff35b63ca0ad2605f526004601cfd"; - -bytes constant FORGE_PROXY_ADMIN_BYTECODE = - hex"60803460b757601f6102f838819003918201601f19168301916001600160401b0383118484101760bb5780849260209460405283398101031260b757516001600160a01b038116810360b7578060601b1560aa57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a360405161022890816100d08239f35b6354a567865f526004601cfd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6004361061021b575f3560e01c8080638da5cb5b146101f25763ad3cb1cc146101c057337f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd554036101af5780639623609d146101295763f2fde38b1461006c57637352d91c5f526004601cfd5b6004357fffffffffffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff82169160601b161561011c57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a37f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd555005b6354a567865f526004601cfd5b50634f1ef2865f527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016024602037604080525f807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601601c3473ffffffffffffffffffffffffffffffffffffffff600435165af1156101a757005b3d5f803e3d5ffd5b6332b2baa35f52336020526024601cfd5b60205f5260056020527f352e302e3000000000000000000000000000000000000000000000000000000060405260605ff35b7f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5545f5260205ff35b63ca0ad2605f526004601cfd"; - -bytes constant PROXY_FORGE_BYTECODE = - hex"60a08060405234603e57306080526113f0908161004382396080518181816101da0152818161073a0152818161089e0152818161092e01526109be0152f35b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c90816314afd79e14610a46575080632abbef15146109e75780633729f922146109575780634314f1201461090a578063525542d614610831578063545e7c61146106e657806374a8f1031461062c5780638b4872b8146105c657806392d9f765146104ee5780639623609d1461044357806399a88ec414610346578063a97b90d5146101525763f00d4b5d146100ab575f80fd5b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e576100dd610aa9565b6100e5610acc565b9063c12fa8d68160601b175f5260205f203381540361013d578260601b15610130578290557f1b185f8166e5b540f041c2132c66d6c691b0674cd3a95ccc9592a43dd64ad6e25f80a3005b63074b52c95f526004601cfd5b6332b2baa35f52336020526024601cfd5b5f80fd5b60807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e57610184610aa9565b61018c610acc565b6044359060643567ffffffffffffffff811161014e576101b0903690600401610aef565b8260601b15610130578360601c338114901517156103395761022f610252926102036040519384927f00000000000000000000000000000000000000000000000000000000000000008a60208601610bac565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282610c13565b6040516106a16102426020820183610c13565b808252610d4f6020830139610c81565b34471061032c578051839160200134f591823b158360601b9081151761031f5760209463c12fa8d69284867fd283ed05905c0eb69fe3ef042c6ad706d8d9c75b138624098de540fa2c011a055f80a463a1337b4d82175f5280865f2055847f3684250ce1e33b790ed973c23080f312db0adb21a6d98c61a5c9ff99e4babc175f80a3175f5280835f2055817f1b185f8166e5b540f041c2132c66d6c691b0674cd3a95ccc9592a43dd64ad6e25f80a373ffffffffffffffffffffffffffffffffffffffff60405191168152f35b63a28c24735f526004601cfd5b63f4d678b85f526004601cfd5b6381e69d9b5f526004601cfd5b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e57610378610aa9565b610380610acc565b9061038a81610cdf565b8160601b63c12fa8d681175f523360205f20540361013d5763a1337b4d175f5260205f209083825414610436575f60405191639623609d83528460208401528560408401526060808401528160808401528136813760a43891601c85019034905af11561041b57508290557f3684250ce1e33b790ed973c23080f312db0adb21a6d98c61a5c9ff99e4babc175f80a3005b3d15610429573d5f823e3d90fd5b6355299b495f526004601cfd5b63dcd488e35f526004601cfd5b61044c36610b1d565b90610458849394610cdf565b8360601b63c12fa8d681175f523360205f20540361013d5763a1337b4d175f5260205f209285845414610436575f918160405194639623609d865287602087015288604087015260608087015281608087015260a086013760a438920190601c85019034905af11561041b57508290557f3684250ce1e33b790ed973c23080f312db0adb21a6d98c61a5c9ff99e4babc175f80a3005b3461014e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff8110156105b95760946001533060601b6002525f6080821061059c5781805b61058d5750806020926017926080016016538160031b610100031b82525b8060d6015f53015f2073ffffffffffffffffffffffffffffffffffffffff60405191168152f35b60019091019060081c80610548565b60179082602093156105b1575b601653610566565b5060806105a9565b63756688fe5f526004601cfd5b3461014e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5763a1337b4d610602610aa9565b60601b175f526020805f205473ffffffffffffffffffffffffffffffffffffffff60405191168152f35b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5761065e610aa9565b61066781610cdf565b8160601b9063c12fa8d682175f5260205f20903382540361013d575f6040519163f2fde38b83523360208401526024389183601c8601915af1156106de5750905f63a1337b4d9255175f525f60208120557f4b0f58242c231a580ee42fe1dd7389c8e7520590afe33c21809305a6014703a15f80a2005b3d5f823e3d90fd5b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e57610718610aa9565b610720610acc565b8060601b156101305761076360405161022f816102035f367f00000000000000000000000000000000000000000000000000000000000000008960208601610bac565b34471061032c5760208151910134f090813b15928260601b9384151761031f5760209363c12fa8d6915f84867fd283ed05905c0eb69fe3ef042c6ad706d8d9c75b138624098de540fa2c011a058380a463a1337b4d82175f5280865f2055847f3684250ce1e33b790ed973c23080f312db0adb21a6d98c61a5c9ff99e4babc175f80a3175f5280835f2055817f1b185f8166e5b540f041c2132c66d6c691b0674cd3a95ccc9592a43dd64ad6e25f80a373ffffffffffffffffffffffffffffffffffffffff60405191168152f35b3461014e5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e57610868610aa9565b6044359067ffffffffffffffff821161014e5761022f610203916108936108c7943690600401610aef565b6040949194519485937f00000000000000000000000000000000000000000000000000000000000000009060208601610bac565b6020815191012060ff5f536035523060601b600152602435601552602060555f205f60355273ffffffffffffffffffffffffffffffffffffffff60405191168152f35b61091336610b1d565b8260601b156101305761022f610763926102036040519384927f00000000000000000000000000000000000000000000000000000000000000008960208601610bac565b60607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e57610989610aa9565b610991610acc565b604435908060601b15610130578160601c338114901517156103395761025260405161022f816102035f367f00000000000000000000000000000000000000000000000000000000000000008a60208601610bac565b3461014e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e576020610a28610a23610aa9565b610cdf565b73ffffffffffffffffffffffffffffffffffffffff60405191168152f35b3461014e5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760209063c12fa8d6610a85610aa9565b60601b175f5273ffffffffffffffffffffffffffffffffffffffff825f2054168152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361014e57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361014e57565b9181601f8401121561014e5782359167ffffffffffffffff831161014e576020838186019501011161014e57565b60607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc82011261014e5760043573ffffffffffffffffffffffffffffffffffffffff8116810361014e579160243573ffffffffffffffffffffffffffffffffffffffff8116810361014e57916044359067ffffffffffffffff821161014e57610ba891600401610aef565b9091565b9293806080957fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09473ffffffffffffffffffffffffffffffffffffffff601f95168752602087015260606040870152816060870152868601375f8582860101520116010190565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610c5457604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b610cdd906020808095946040519684889551918291018487015e8401908282015f8152815193849201905e01015f8152037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283610c13565b565b6001906094825360601b6002525f9060808110610d33579081825b610d215760179250816080016016538160031b610100031b82525b8060d6015f53015f2090565b9060019260081c928391019190610cfa565b908160179215610d46575b601653610d15565b506080610d3e56fe60a0806040526106a18038038091610017828561023a565b83398101906060818303126102225761002f8161025d565b9161003c6020830161025d565b604083015190926001600160401b038211610222570181601f820112156102225780516001600160401b0381116102265760405191610085601f8301601f19166020018461023a565b81835260208301936020838301011161022257815f926020809301865e83010152604051936101206102fb6100bd602082018861023a565b80875260208701906103a68239604080516001600160a01b039097166020888101918252808952916100ef908961023a565b6040519788938385019a5180918c5e840190838201905f8252519283915e01015f815203601f19810186528561023a565b803b1561021557807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a28151156101ff575f92389251915af4156101f7575b51905ff08060601b156101f757807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610355806020527f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f60405fa1608052604051610134908161027282396080518160060152f35b3d5f803e3d5ffd5b505050341561018457636fb1b0e95f526004601cfd5b6368155f9a5f526004601cfd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b601f909101601f19168101906001600160401b0382119082101761022657604052565b51906001600160a01b03821682036102225756fe60806040527f0000000000000000000000000000000000000000000000000000000000000000331461006857365f80375f3836827f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d5f803e15610064573d5ff35b3d5ffd5b634f1ef2865f3560e01c036101275773ffffffffffffffffffffffffffffffffffffffff60043516803b1561011a57807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55807fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a260443590811561010457815f92606484378238925af4156100fc57005b3d5f803e3d5ffd5b50503461010d57005b636fb1b0e95f526004601cfd5b6368155f9a5f526004601cfd5b63d2b576ec5f526004601cfd60803460b757601f6102fb38819003918201601f19168301916001600160401b0383118484101760bb5780849260209460405283398101031260b757516001600160a01b038116810360b7578060601b1560aa57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a360405161022b90816100d08239f35b6354a567865f526004601cfd5b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6004361061021e575f3560e01c8080638da5cb5b146101f55763ad3cb1cc146101c357337f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd554036101b25780639623609d146101295763f2fde38b1461006c57637352d91c5f526004601cfd5b6004357fffffffffffffffffffffffffffffffffffffffff00000000000000000000000073ffffffffffffffffffffffffffffffffffffffff82169160601b161561011c57807f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a37f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd555005b6354a567865f526004601cfd5b50634f1ef2865f527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016024602037604080525f387fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601601c3473ffffffffffffffffffffffffffffffffffffffff600435165af1156101a757005b6040513d5f823e3d90fd5b6332b2baa35f52336020526024601cfd5b60205f5260056020527f352e302e3000000000000000000000000000000000000000000000000000000060405260605ff35b7f9bc353c4ee8d049c7cb68b79467fc95d9015a8a82334bd0e61ce699e20cb5bd5545f5260205ff35b63ca0ad2605f526004601cfd"; diff --git a/test/CreateXFactory.t.sol b/test/CreateXFactory.t.sol index 47c0514..8ee1a0e 100644 --- a/test/CreateXFactory.t.sol +++ b/test/CreateXFactory.t.sol @@ -2,12 +2,13 @@ pragma solidity ^0.8.30; import {Test} from "forge-std/Test.sol"; +import {Config} from "forge-std/Config.sol"; import {CreateXFactory, ICreateXFactory} from "src/CreateXFactory.sol"; import {CreateX} from "src/CreateX.sol"; import {MockERC20} from "test/mocks/MockERC20.sol"; import {MockTarget} from "test/mocks/MockTarget.sol"; -contract CreateXFactoryTest is Test { +contract CreateXFactoryTest is Test, Config { uint256 internal snapshotId = type(uint256).max; CreateXFactory internal factory; @@ -21,14 +22,14 @@ contract CreateXFactoryTest is Test { } function setUp() public { - factory = new CreateXFactory(); + vm.makePersistent(address(factory = new CreateXFactory())); } function test_fuzz_createX(bool protected, address deployer, uint96 identifier, uint256 value) public impersonate(deployer, value) { - bytes memory initCode = abi.encodePacked(type(MockTarget).creationCode); + bytes memory initCode = type(MockTarget).creationCode; bytes32 initCodeHash = keccak256(initCode); bytes32 salt = generateSalt(deployer, identifier, protected); @@ -71,8 +72,8 @@ contract CreateXFactoryTest is Test { predicted = factory.computeCreateAddress(vm.getNonce(address(factory))), deployer ); - instance = - factory.createX{value: value}(ICreateXFactory.CreationType.Clone, abi.encodePacked(implementation), salt); + initCode = abi.encodePacked(implementation); + instance = factory.createX{value: value}(ICreateXFactory.CreationType.Clone, initCode, salt); assertEq(instance, predicted); assertEq(instance.balance, value); revertToState(); @@ -82,16 +83,12 @@ contract CreateXFactoryTest is Test { predicted = factory.computeCloneDeterministicAddress(implementation, salt), deployer, salt ); - instance = factory.createX{value: value}( - ICreateXFactory.CreationType.CloneDeterministic, abi.encodePacked(implementation), salt - ); + instance = factory.createX{value: value}(ICreateXFactory.CreationType.CloneDeterministic, initCode, salt); assertEq(instance, predicted); assertEq(instance.balance, value); } - function test_fuzz_computeCreateXAddress(bool protected, address deployer, uint96 identifier, bytes32 hash) - public - { + function test_fuzz_computeCreateXAddress(bool protected, address deployer, uint96 identifier, bytes32 hash) public { if (identifier >= type(uint64).max) { vm.expectRevert(CreateX.InvalidNonce.selector); factory.computeCreateXAddress(ICreateXFactory.CreationType.CREATE, hash, bytes32(uint256(identifier))); @@ -130,7 +127,7 @@ contract CreateXFactoryTest is Test { } function test_fuzz_create(address deployer, uint256 value) public impersonate(deployer, value) { - bytes memory initCode = abi.encodePacked(type(MockTarget).creationCode); + bytes memory initCode = type(MockTarget).creationCode; address predicted = vm.computeCreateAddress(address(factory), vm.getNonce(address(factory))); vm.expectEmit(true, true, true, true); @@ -161,7 +158,7 @@ contract CreateXFactoryTest is Test { public impersonate(deployer, value) { - bytes memory initCode = abi.encodePacked(type(MockTarget).creationCode); + bytes memory initCode = type(MockTarget).creationCode; bytes32 initCodeHash = keccak256(initCode); bytes32 salt = generateSalt(deployer, identifier, protected); address predicted = computeCreate2Address(address(factory), initCodeHash, salt); @@ -196,7 +193,7 @@ contract CreateXFactoryTest is Test { public impersonate(deployer, value) { - bytes memory initCode = abi.encodePacked(type(MockTarget).creationCode); + bytes memory initCode = type(MockTarget).creationCode; bytes32 salt = generateSalt(deployer, identifier, protected); address predicted = computeCreate3Address(address(factory), salt); @@ -226,47 +223,25 @@ contract CreateXFactoryTest is Test { } function test_create3_chainAgnosticDeployment() public { - vm.makePersistent(address(factory)); + _loadConfigAndForks("./config/test.toml", false); + + uint256[] memory chains = config.getChainIds(); + assertGt(chains.length, 0); bytes memory initCode = bytes.concat(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)); bytes32 salt = generateSalt(address(this)); - vm.createSelectFork("ethereum"); + vm.selectFork(forkOf[chains[0]]); address instance = factory.create3(initCode, salt); - vm.createSelectFork("optimism"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("bnb"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("polygon"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("unichain"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("fantom"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("base"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("arbitrum"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("avalanche"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("scroll"); - assertEq(instance, factory.create3(initCode, salt)); - - vm.createSelectFork("linea"); - assertEq(instance, factory.create3(initCode, salt)); + for (uint256 i = 1; i < chains.length; ++i) { + vm.selectFork(forkOf[chains[i]]); + assertEq(instance, factory.create3(initCode, salt)); + } } function test_create3_revertsOnSameSaltDeployments() public { - bytes memory mockInitCode = abi.encodePacked(type(MockTarget).creationCode); + bytes memory mockInitCode = type(MockTarget).creationCode; bytes memory erc20InitCode = bytes.concat(type(MockERC20).creationCode, abi.encode("Mock Token", "MOCK", 18)); bytes32 salt = generateSalt(address(this)); @@ -381,7 +356,7 @@ contract CreateXFactoryTest is Test { return computeCreate2Address(deployer, initCodeHash, salt); } - function generateSalt(address caller) internal returns (bytes32 salt) { + function generateSalt(address caller) internal view returns (bytes32 salt) { return generateSalt(caller, uint96(vm.randomUint(type(uint96).min, type(uint96).max))); }