Last active
June 5, 2023 11:14
-
-
Save imqdee/ffb2dcc9e7285c673299be918ea3bab1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| contract Deployer { | |
| event Deployed(address); | |
| // This is the runtime code of the contract we would like to deploy | |
| // Example: `contract DummyContract { uint256 public nonce; }` | |
| bytes CONTRACT_RUNTIME_CODE = | |
| hex"6080604052348015600e575f80fd5b50600436106026575f3560e01c8063affed0e014602a575b5f80fd5b60315f5481565b60405190815260200160405180910390f3"; | |
| // This handmade creation code is responsible of returning the creation code of dynamic length | |
| // ⚠️ It assumes the contract we would like to deploy doesn't have a constructor (!!) | |
| // ℹ️ If the size of the precompile is fixed, we can simplify the sequence | |
| bytes constant CREATION_CODE = hex"80_60_0E_60_00_39_60_00_F3"; | |
| /* | |
| 0x00 0x63 0x63XXXXXX PUSH4 _code.length size | |
| 0x01 0x80 0x80 DUP1 size size | |
| 0x02 0x60 0x600e PUSH1 14 14 size size | |
| 0x03 0x60 0x6000 PUSH1 00 0 14 size size | |
| 0x04 0x39 0x39 CODECOPY size | |
| 0x05 0x60 0x6000 PUSH1 00 0 size | |
| 0x06 0xf3 0xf3 RETURN | |
| <CODE> | |
| */ | |
| function deploy(bytes calldata precompile) external returns (address addr) { | |
| uint256 finalRuntimeCodeLength = CONTRACT_RUNTIME_CODE.length + precompile.length; | |
| bytes memory bytecode = abi.encodePacked( | |
| hex"63", // PUSH4 | |
| uint32(finalRuntimeCodeLength), // <length> | |
| // responsible of returning the dynamic runtime code | |
| CREATION_CODE, | |
| // concatenation of both runtime code | |
| bytes.concat(CONTRACT_RUNTIME_CODE, precompile) | |
| ); | |
| assembly { | |
| addr := create(0, add(bytecode, 0x20), mload(bytecode)) | |
| // if the `create` opcode fails, the address is equals to 0 | |
| if iszero(extcodesize(addr)) { | |
| revert(0, 0) | |
| } | |
| } | |
| emit Deployed(addr); | |
| } | |
| function deploy(bytes calldata precompile, bytes32 salt) | |
| external | |
| returns (address addr) | |
| { | |
| uint256 finalRuntimeCodeLength = CONTRACT_RUNTIME_CODE.length + precompile.length; | |
| bytes memory bytecode = abi.encodePacked( | |
| hex"63", // PUSH4 | |
| uint32(finalRuntimeCodeLength), // <length> | |
| // responsible of returning the dynamic runtime code | |
| CREATION_CODE, | |
| // concatenation of both runtime code | |
| bytes.concat(CONTRACT_RUNTIME_CODE, precompile) | |
| ); | |
| assembly { | |
| addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt) | |
| // if the `create` opcode fails, the address is equals to 0 | |
| if iszero(extcodesize(addr)) { | |
| revert(0, 0) | |
| } | |
| } | |
| emit Deployed(addr); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment