From dd7a89914ae4744202f67a845df5193315320129 Mon Sep 17 00:00:00 2001 From: dyedm1 Date: Sat, 7 Oct 2023 14:45:52 -0400 Subject: [PATCH] feat: simplify bootstrap code and remove PUSH0 usage --- README.md | 10 ++++----- src/Create4Factory.sol | 47 +++++++++++++++------------------------ test/Create4Factory.t.sol | 5 ++--- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index fe7df04..80353da 100644 --- a/README.md +++ b/README.md @@ -23,19 +23,17 @@ ### Initcode for address derivation For `Create4Factory`, the `initCode` is constructed as follows: -- Code segment 1: `5f5f5f5f5f73` -- `Create4Factory` address: `ffffffffffffffffffffffffffffffffffffffff` -- Code segment 2: `5af13d5f5f3e3d5ff3` -- Deployer address (user calling `create4`): `ffffffffffffffffffffffffffffffffffffffff` +- Executable constructor: `3636363636335af13d36363e3d36f3` +- Deployer address (user calling `create4`): `ffffffffffffffffffffffffffffffffffffffff` (20-byte salt) -Result: `0x5f5f5f5f5f735af13d5f5f3e3d5ff3` +Result: `0x3636363636335af13d36363e3d36f3` #### Example If we have - `Create4Factory` address: `0xe358511cd9bf45c8a4d4aaf96ad5f6234ad20282` (note: not the real-world address!) - Deployer address: `0xab5801a7d398351b8be11c439e05c5b3259aec9b` (Vb) Our `initCode` would be: -`0x5f5f5f5f5f73e358511cd9bf45c8a4d4aaf96ad5f6234ad202825af13d5f5f3e3d5ff3ab5801a7d398351b8be11c439e05c5b3259aec9b` +`0x3636363636335af13d36363e3d36f3ab5801a7d398351b8be11c439e05c5b3259aec9b` ### Features diff --git a/src/Create4Factory.sol b/src/Create4Factory.sol index 7639a23..b059438 100644 --- a/src/Create4Factory.sol +++ b/src/Create4Factory.sol @@ -10,34 +10,27 @@ pragma solidity ^0.8.20; */ contract Create4Factory { /* - [26 BYTES] - PUSH0 // retSize: 0 - PUSH0 // retOffset: 0 - PUSH0 // argsSize: 0 - PUSH0 // argsOffset: 0 - PUSH0 // value: 0 - PUSH20 (0x0000000000000000000000000000000000000000) // FACTORY ADDRESS(THIS), FILLED DYNAMICALLY - Right-padded with 0s to 32 bytes - */ - bytes32 internal constant BOOTSTRAP_CODE_SECTION_1 = - hex"5f5f5f5f5f73000000000000000000000000000000000000000000000000"; - - /* - [29 BYTES] + [35 BYTES] + CALLDATASIZE // retSize: 0 + CALLDATASIZE // retOffset: 0 + CALLDATASIZE // argsSize: 0 + CALLDATASIZE // argsOffset: 0 + CALLDATASIZE // value: 0 + CALLER // Create4Factory GAS // gas (gas remaining in frame) CALL RETURNDATASIZE // size (of returned code to copy) - PUSH0 // offset: 0 - PUSH0 // destOffset: 0 + CALLDATASIZE // offset: 0 + CALLDATASIZE // destOffset: 0 RETURNDATACOPY RETURNDATASIZE // size (of code to return/deploy) - PUSH0 // offset: 0 + CALLDATASIZE // offset: 0 RETURN (0x0000000000000000000000000000000000000000) // MSG.SENDER, FILLED DYNAMICALLY (appended for frontrunning protection) Right-padded with 0s to 32 bytes */ - bytes32 internal constant BOOTSTRAP_CODE_SECTION_2 = - hex"5af13d5f5f3e3d5ff30000000000000000000000000000000000000000000000"; + bytes32 internal constant BOOTSTRAP_CODE = hex"3636363636335af13d36363e3d36f30000000000000000000000000000000000"; + uint256 internal constant UINT256_MAX = 2 ** 256 - 1; @@ -66,12 +59,10 @@ contract Create4Factory { currentDeployment = deployedCode; assembly { - mstore(0, BOOTSTRAP_CODE_SECTION_1) - mstore(6, shl(96, address())) - mstore(26, BOOTSTRAP_CODE_SECTION_2) - mstore(35, shl(96, caller())) + mstore(0, BOOTSTRAP_CODE) + mstore(15, shl(96, caller())) - newContract := create2(0, 0, 55, salt) + newContract := create2(0, 0, 35, salt) } } @@ -101,12 +92,10 @@ contract Create4Factory { tstore(i, mload(add(deployedCode, add(32, mul(i, 32))))) } - mstore(0, BOOTSTRAP_CODE_SECTION_1) - mstore(6, shl(96, address())) - mstore(26, BOOTSTRAP_CODE_SECTION_2) - mstore(35, shl(96, caller())) + mstore(0, BOOTSTRAP_CODE) + mstore(15, shl(96, caller())) - newContract := create2(0, 0, 55, salt) + newContract := create2(0, 0, 35, salt) } } diff --git a/test/Create4Factory.t.sol b/test/Create4Factory.t.sol index d5d0143..f556ce8 100644 --- a/test/Create4Factory.t.sol +++ b/test/Create4Factory.t.sol @@ -6,8 +6,7 @@ import {Test, console2} from "forge-std/Test.sol"; import {Create4Factory} from "src/Create4Factory.sol"; contract TestCreate4Factory is Test { - bytes6 internal constant BOOTSTRAP_CODE_SECTION_1 = hex"5f5f5f5f5f73"; - bytes9 internal constant BOOTSTRAP_CODE_SECTION_2 = hex"5af13d5f5f3e3d5ff3"; + bytes15 internal constant BOOTSTRAP_CODE = hex"3636363636335af13d36363e3d36f3"; address internal constant EIP_1153_MAGIC = address(0x4549502d31313533); Create4Factory internal C4F; @@ -15,7 +14,7 @@ contract TestCreate4Factory is Test { function expectedAddress(address deployer, bytes32 salt) internal view returns (address) { bytes32 bootstrapCodeHash = keccak256( abi.encodePacked( - BOOTSTRAP_CODE_SECTION_1, bytes20(address(C4F)), BOOTSTRAP_CODE_SECTION_2, bytes20(address(deployer)) + BOOTSTRAP_CODE, bytes20(address(deployer)) ) );