├── .github └── workflows │ └── test.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── foundry.toml ├── script └── DeployTest.s.sol ├── src ├── VersionLib.huff ├── VersionLib.sol ├── detectors │ ├── Constants.sol │ └── Shanghai.huff ├── examples │ └── Choice.huff └── interfaces │ └── ICreate2Factory.sol └── test ├── VersionLib.t.sol ├── mocks └── ViewVersionGet.huff └── utils └── Create2Constants.sol /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: workflow_dispatch 4 | 5 | env: 6 | FOUNDRY_PROFILE: ci 7 | 8 | jobs: 9 | check: 10 | strategy: 11 | fail-fast: true 12 | 13 | name: Foundry project 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | 20 | - name: Install Foundry 21 | uses: foundry-rs/foundry-toolchain@v1 22 | with: 23 | version: nightly 24 | 25 | - name: Run Forge build 26 | run: | 27 | forge --version 28 | forge build --sizes 29 | id: build 30 | 31 | - name: Run Forge tests 32 | run: | 33 | forge test -vvv 34 | id: test 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiler files 2 | cache/ 3 | out/ 4 | 5 | # Ignores development broadcast logs 6 | broadcast 7 | 8 | # Docs 9 | docs/ 10 | 11 | # Dotenv file 12 | .env 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/forge-std"] 2 | path = lib/forge-std 3 | url = https://github.com/foundry-rs/forge-std 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Philippe Dumonet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🔍 Version Detector 2 | 3 | A library for runtime EVM version detection. 4 | 5 | ## Motivation 6 | 7 | As the EVM is improved and hardforks are activated the versions and therefore capabilities of 8 | different EVM chains may differ. It may be useful to be able to do a runtime check of the EVM 9 | version to ensure that contracts are either not deployed to chains where some of its instructions 10 | are unsupported or to simply choose a compatible runtime implementation at deployment. 11 | 12 | ## Recognized Versions 13 | 14 | |EVM Version / Version Cutoff| Indicator|Version Enum & Value| 15 | |----------------------------|----------|--------------------| 16 | |Unknown|Detectors missing on the target chain / unable to be deployed|`Version.Unknown` (`0x0`)| 17 | |Pre-Shanghai|`PUSH0` (`0x5f`) uses more than 2 gas / reverts|`Version.PreShanghai` (`0x1`)| 18 | |Post-Shanghai|`PUSH0` (`0x5f`) uses 2 or less gas & does not revert|`Version.PreShanghai` (`0x2`)| 19 | 20 | ## Usage 21 | 22 | First install this repo as a dependency into your foundry project: 23 | 24 | ```bash 25 | forge install philogy/version-detector --no-commit 26 | ``` 27 | 28 | ### Solidity 29 | 30 | In your contract import and then use the library e.g.: 31 | 32 | ```solidity 33 | // SPDX-License-Identifier: MIT 34 | pragma solidity 0.8.21; 35 | 36 | import {VersionLib, Version} from "version-detector/VersionLib.sol"; 37 | 38 | contract OnlyShanghai { 39 | constructor() { 40 | require(VersionLib.getVersion() >= Version.PostShanghai, "Incorrect Version"); 41 | } 42 | } 43 | ``` 44 | 45 | ### Huff 46 | 47 | In your code `#include` the library: 48 | 49 | ``` 50 | #include "../lib/version-detector/src/VersionLib.huff" 51 | ``` 52 | 53 | You can then use the `GET_VERSION` macro and version constants (`VERSION_UNKNOWN`, `VERSION_PRE_SHANGHAI` `VERSION_POST_SHANGHAI`): 54 | 55 | ``` 56 | #include "../lib/version-detector/src/VersionLib.huff" 57 | 58 | #define table V1_DEFAULT { 59 | 0x3d 60 | } 61 | 62 | #define table V2_SHANGHAI { 63 | 0x5f 64 | } 65 | 66 | #define macro CONSTRUCTOR() = takes(0) returns(0) { 67 | GET_VERSION() 68 | [VERSION_POST_SHANGHAI] 69 | gt 70 | iszero 71 | v2 jumpi 72 | default: 73 | __tablesize(V1_DEFAULT) 74 | dup1 75 | __tablestart(V1_DEFAULT) 76 | 0x0 77 | codecopy 78 | 0x0 79 | return 80 | v2: 81 | __tablesize(V2_SHANGHAI) 82 | dup1 83 | __tablestart(V2_SHANGHAI) 84 | 0x0 85 | codecopy 86 | 0x0 87 | return 88 | } 89 | 90 | #define macro MAIN() = takes(0) returns(0) { } 91 | ``` 92 | 93 | ## Documentation 94 | ### Solidity 95 | #### [`VersionLib`](./src/VersionLib.sol) 96 | 97 | **`getVersion() returns (Version)`** 98 | 99 | A _non-view_ method that returns `Version` indicating the current chain's EVM version. May do a one time deployment of detectors if missing on the current chain. Expects the [`Immutable Create2 Factory`](https://etherscan.io/address/0x0000000000FFe8B47B3e2130213B802212439497) to deployed on the current chain and will revert if not deployed. 100 | 101 | **`getVersionView() view returns (Version)`** 102 | 103 | Similar to `getVersion` except that it will not deploy any missing detector contracts. May return 104 | `Version.Unknown` if required detectors are missing on the current chain. 105 | 106 | #### [`Version`](./src/VersionLib.sol) 107 | 108 | **`toString() pure returns (string memory)`** 109 | 110 | Returns a string representation of the version, can be useful for debugging. (Implemented as 111 | `VersionLib.toString(Version version)` and mounted to the `Version` type via `using VersionLib for 112 | Version global;`). 113 | 114 | ### Huff 115 | #### [`GET_VERSION()`](./src/VersionLib.huff) 116 | 117 | Similar to the Solidity `VersionLib.getVersion` function, the `GET_VERSION` macro will retrieve and push the version value as 118 | a full word onto the stack. It'll deploy any detectors if missing and requires the same create2 119 | factory to already be deployed on the chain. 120 | 121 | #### [`GET_VERSION_VIEW()`](./src/VersionLib.huff) 122 | 123 | Similar to the Solidity `VersionLib.getVersionView` function, the `GET_VERSION_VIEW` macro will 124 | check for the detectors and push the version to the stack, it will not deploy missing detector 125 | contracts and will simple push the `Unknown` version (`0x0`) onto the stack if any necessary 126 | contracts are missing. 127 | -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = "src" 3 | out = "out" 4 | libs = ["lib"] 5 | 6 | evm_version = "paris" 7 | 8 | # See more config options https://github.com/foundry-rs/foundry/tree/master/config 9 | -------------------------------------------------------------------------------- /script/DeployTest.s.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.21; 3 | 4 | import {Script} from "forge-std/Script.sol"; 5 | import {VersionLib} from "src/VersionLib.sol"; 6 | 7 | contract Dud { 8 | function version() external returns (string memory) { 9 | return VersionLib.getVersion().toString(); 10 | } 11 | } 12 | 13 | /// @author philogy 14 | contract DeployTestScript is Script { 15 | function run() public { 16 | vm.startBroadcast(vm.envUint("PRIV_KEY")); 17 | new Dud(); 18 | vm.stopBroadcast(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/VersionLib.huff: -------------------------------------------------------------------------------- 1 | // ===================== Factory Constants ===================== 2 | #define constant FACTORY_ADDR = 0x0000000000FFe8B47B3e2130213B802212439497 3 | #define function safeCreate2(bytes32, bytes) nonpayable returns (address) 4 | 5 | // ==================== Shanghai Constants ===================== 6 | #define constant SHANGHAI_ADDR = 0x000000005ea0cBe63A65f3383BFC4541c9520Ab5 7 | #define constant SHANGHAI_SALT = 0x00000000000000000000000000000000000000001510b57b210380000966a689 8 | #define constant SHANGHAI_CODE = 0x0a60018060093d393df35f // length + code 9 | #define constant SHANGHAI_CODE_OFFSET = 0x6a // length + code 10 | // Size of total `safeCreate2` calldata payload 11 | #define constant SHANGHAI_DEPLOY_SIZE = 0x6e 12 | 13 | // ===================== Other Definitions ===================== 14 | #define error MissingCreate2Factory() 15 | #define error ShanghaiDetectorDeployFailed() 16 | 17 | #define constant VERSION_UNKNOWN = 0x0 18 | #define constant VERSION_PRE_SHANGHAI = 0x1 19 | #define constant VERSION_POST_SHANGHAI = 0x2 20 | 21 | #define macro GET_VERSION() = takes(0) returns(1) { 22 | 0x0 0x0 0x0 0x0 // [0, 0, 0, 0] 23 | [SHANGHAI_ADDR] dup1 dup1 // [0, 0, 0, 0, shanghai_addr, shanghai_addr, shanghai_addr] 24 | _ENSURE_SHANGHAI_DEPLOYED() // [0, 0, 0, 0, shanghai_addr] 25 | 0x2 // [0, 0, 0, 0, shanghai_addr, 2] 26 | staticcall // [success] 27 | [VERSION_PRE_SHANGHAI] // [success, VERSION_PRE_SHANGHAI] 28 | add // [version] 29 | // returns: [version] 30 | } 31 | 32 | #define macro GET_VERSION_VIEW() = takes(0) returns(1) { 33 | 0x0 0x0 0x0 0x0 // [0, 0, 0, 0] 34 | [SHANGHAI_ADDR] dup1 // [0, 0, 0, 0, shanghai_addr, shanghai_addr] 35 | extcodesize // [0, 0, 0, 0, shanghai_addr, shanghai_addr.code.length] 36 | has_shanghai_detector jumpi // [0, 0, 0, 0, shanghai_addr] 37 | // Detector not deployed but view, so return unknown (0x0). 38 | pop pop pop pop // [0] 39 | has_result jump // [0] 40 | has_shanghai_detector: // [0, 0, 0, 0, shanghai_addr] 41 | 0x2 // [0, 0, 0, 0, shanghai_addr, 2] 42 | staticcall // [success] 43 | [VERSION_PRE_SHANGHAI] // [success, VERSION_PRE_SHANGHAI] 44 | add // [version] 45 | has_result: // [version] 46 | } 47 | 48 | #define macro _ENSURE_SHANGHAI_DEPLOYED() = takes(2) returns(0) { 49 | extcodesize // [shanghai_addr, shanghai_addr.code.length] 50 | shanghai_deployed jumpi // [shanghai_addr] 51 | // Shanghai detector not deployed. 52 | _CHECK_FACTORY() // [shanghai_addr, factory_addr] 53 | // -- Call `safeCreate2(SHANGHAI_SALT, SHANGHAI_CODE)` 54 | __FUNC_SIG(safeCreate2) // [shanghai_addr, factory_addr, safeCreate2.selector] 55 | 0x0 // [shanghai_addr, factory_addr, safeCreate2.selector, 0x0] 56 | mstore // [shanghai_addr, factory_addr] 57 | [SHANGHAI_SALT] // [shanghai_addr, factory_addr, shanghai_salt] 58 | 0x20 // [shanghai_addr, factory_addr, shanghai_salt, 0x20] 59 | mstore // [shanghai_addr, factory_addr] 60 | 0x40 dup1 // [shanghai_addr, factory_addr, 0x40, 0x40] 61 | mstore // [shanghai_addr, factory_addr] 62 | [SHANGHAI_CODE] // [shanghai_addr, factory_addr, shanghai_code] 63 | [SHANGHAI_CODE_OFFSET] // [shanghai_addr, factory_addr, shanghai_code, shanghai_code_offset] 64 | mstore // [shanghai_addr, factory_addr] 65 | 0x0 // [shanghai_addr, factory_addr, 0] 66 | [SHANGHAI_DEPLOY_SIZE] // [shanghai_addr, factory_addr, 0, size] 67 | 0x1c // [shanghai_addr, factory_addr, 0, size, 0x1c] 68 | 0x0 // [shanghai_addr, factory_addr, 0, size, 0x1c, 0] 69 | 0x20 // [shanghai_addr, factory_addr, 0, size, 0x1c, 0, 0x20] 70 | swap5 // [shanghai_addr, 0x20 , 0, size, 0x1c, 0, factory_addr] 71 | gas // [shanghai_addr, 0x20 , 0, size, 0x1c, 0, factory_addr, gas] 72 | call // [shanghai_addr, success] 73 | // -- Verify result and success. 74 | swap1 // [success, shanghai_addr] 75 | 0x0 // [success, shanghai_addr, 0] 76 | mload // [success, shanghai_addr, ret_addr] 77 | eq // [success, shanghai_addr == ret_addr] 78 | and // [success && shanghai_addr == ret_addr] 79 | shanghai_deployed jumpi // [] 80 | __FUNC_SIG(ShanghaiDetectorDeployFailed) 81 | // [ShanghaiDetectorDeployFailed.selector] 82 | _REVERT() // [] -- end 83 | shanghai_deployed: // [] 84 | // returns: [] 85 | } 86 | 87 | #define macro _CHECK_FACTORY() = takes(0) returns(1) { 88 | [FACTORY_ADDR] dup1 // [factory_addr, factory_addr] 89 | extcodesize // [factory_addr, factory_addr.code.length] 90 | factory_exists jumpi // [factory_addr] 91 | __FUNC_SIG(MissingCreate2Factory) 92 | // [factory_addr, MissingCreate2Factory.selector] 93 | _REVERT() // [factory_addr] -- end 94 | factory_exists: // [factory_addr] 95 | } 96 | 97 | #define macro _REVERT() = takes(1) returns(0) { 98 | // takes: [error_selector] 99 | 0x0 // [error_selector, 0] 100 | mstore // [] 101 | 0x04 // [0x04] 102 | 0x1c // [0x04, 0x1c] 103 | revert // [] -- end 104 | } 105 | -------------------------------------------------------------------------------- /src/VersionLib.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | import {ICreate2Factory} from "./interfaces/ICreate2Factory.sol"; 5 | import {Shanghai} from "./detectors/Constants.sol"; 6 | 7 | enum Version { 8 | Unknown, 9 | PreShanghai, 10 | PostShanghai 11 | } 12 | 13 | using VersionLib for Version global; 14 | 15 | /// @author philogy 16 | library VersionLib { 17 | // ======================== Foundation ========================= 18 | ICreate2Factory internal constant FACTORY = ICreate2Factory(0x0000000000FFe8B47B3e2130213B802212439497); 19 | 20 | error MissingCreate2Factory(); 21 | error UnrecognizedVersion(); 22 | 23 | function getVersion() internal returns (Version) { 24 | _ensureShanghai(); 25 | return getVersionView(); 26 | } 27 | 28 | function getVersionView() internal view returns (Version) { 29 | if (Shanghai.ADDR.code.length == 0) return Version.Unknown; 30 | (bool success,) = Shanghai.ADDR.staticcall{gas: 2}(new bytes(0)); 31 | return success ? Version.PostShanghai : Version.PreShanghai; 32 | } 33 | 34 | function toString(Version version) internal pure returns (string memory s) { 35 | /// @solidity memory-safe-assembly 36 | assembly { 37 | s := mload(0x40) 38 | mstore(0x40, add(s, 0x40)) 39 | switch version 40 | case 0 { 41 | /* Unknown */ 42 | mstore(s, 15) 43 | mstore(add(s, 0x20), "Version.Unknown") 44 | } 45 | case 1 { 46 | /* PreShanghai */ 47 | mstore(s, 19) 48 | mstore(add(s, 0x20), "Version.PreShanghai") 49 | } 50 | case 2 { 51 | /* PostShanghai */ 52 | mstore(s, 20) 53 | mstore(add(s, 0x20), "Version.PostShanghai") 54 | } 55 | default { 56 | mstore(0x00, 0x3ad2e043) // `UnrecognizedVersion()` 57 | revert(0x1c, 0x04) 58 | } 59 | } 60 | } 61 | 62 | function _ensureShanghai() internal { 63 | if (Shanghai.ADDR.code.length == 0) { 64 | if (address(FACTORY).code.length == 0) revert MissingCreate2Factory(); 65 | assert(FACTORY.safeCreate2(Shanghai.SALT, Shanghai.CODE) == Shanghai.ADDR); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/detectors/Constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | /// @author philogy 5 | library Shanghai { 6 | bytes32 internal constant SALT = 0x00000000000000000000000000000000000000001510b57b210380000966a689; 7 | bytes internal constant CODE = hex"60018060093d393df35f"; 8 | address internal constant ADDR = 0x000000005ea0cBe63A65f3383BFC4541c9520Ab5; 9 | } 10 | -------------------------------------------------------------------------------- /src/detectors/Shanghai.huff: -------------------------------------------------------------------------------- 1 | #define macro MAIN() = takes(0) returns(0) { 2 | push0 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/Choice.huff: -------------------------------------------------------------------------------- 1 | #include "../VersionLib.huff" 2 | 3 | #define table V1_DEFAULT { 4 | 0x3d 5 | } 6 | 7 | #define table V2_SHANGHAI { 8 | 0x5f 9 | } 10 | 11 | #define macro CONSTRUCTOR() = takes(0) returns(0) { 12 | GET_VERSION(0x0) 13 | [VERSION_POST_SHANGHAI] 14 | gt 15 | iszero 16 | v2 jumpi 17 | default: 18 | __tablesize(V1_DEFAULT) 19 | dup1 20 | __tablestart(V1_DEFAULT) 21 | 0x0 22 | codecopy 23 | 0x0 24 | return 25 | v2: 26 | __tablesize(V2_SHANGHAI) 27 | dup1 28 | __tablestart(V2_SHANGHAI) 29 | 0x0 30 | codecopy 31 | 0x0 32 | return 33 | } 34 | 35 | #define macro MAIN() = takes(0) returns(0) { } 36 | -------------------------------------------------------------------------------- /src/interfaces/ICreate2Factory.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | interface ICreate2Factory { 5 | function safeCreate2(bytes32 salt, bytes calldata initCode) external returns (address addr); 6 | } 7 | -------------------------------------------------------------------------------- /test/VersionLib.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity 0.8.21; 3 | 4 | import {Test} from "forge-std/Test.sol"; 5 | import {VersionLib, Version} from "src/VersionLib.sol"; 6 | import {Shanghai} from "src/detectors/Constants.sol"; 7 | import {console2 as console} from "forge-std/console2.sol"; 8 | import {FACTORY_CODE, FACTORY_ADDR} from "./utils/Create2Constants.sol"; 9 | 10 | /// @author philogy 11 | contract VersionLibTest is Test { 12 | function setUp() public { 13 | vm.etch(FACTORY_ADDR, FACTORY_CODE); 14 | } 15 | 16 | function testVersion() public { 17 | console.log("version: %s", VersionLib.getVersion().toString()); 18 | } 19 | 20 | function testHuffChoice() public { 21 | address deployed = deployHuffWithVersion("src/examples/Choice.huff", "paris"); 22 | emit log_named_bytes("deployed.code", deployed.code); 23 | } 24 | 25 | function testViewVersionUnknown() public { 26 | address viewVersion = deployHuffWithVersion("test/mocks/ViewVersionGet.huff", "paris"); 27 | (bool success, bytes memory ret) = viewVersion.staticcall(new bytes(0)); 28 | assertTrue(success); 29 | uint256 v = abi.decode(ret, (uint256)); 30 | assertEq(v, 0); 31 | } 32 | 33 | function testViewVersionKnown() public { 34 | address viewVersion = deployHuffWithVersion("test/mocks/ViewVersionGet.huff", "paris"); 35 | VersionLib.FACTORY.safeCreate2(Shanghai.SALT, Shanghai.CODE); 36 | (bool success, bytes memory ret) = viewVersion.staticcall(new bytes(0)); 37 | assertTrue(success); 38 | uint256 v = abi.decode(ret, (uint256)); 39 | console.log("version: %d", v); 40 | } 41 | 42 | function deployHuffWithVersion(string memory file, string memory version) internal returns (address deployed) { 43 | bytes memory code = getHuffWithVersion(file, version); 44 | /// @solidity memory-safe-assembly 45 | assembly { 46 | deployed := create(0, add(code, 0x20), mload(code)) 47 | } 48 | assertTrue(deployed != address(0), "DEPLOY_FAILED"); 49 | } 50 | 51 | function getHuffWithVersion(string memory file, string memory version) internal returns (bytes memory code) { 52 | string[] memory args = new string[](5); 53 | args[0] = "huffc"; 54 | args[1] = "-b"; 55 | args[2] = file; 56 | args[3] = "-e"; 57 | args[4] = version; 58 | code = vm.ffi(args); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/mocks/ViewVersionGet.huff: -------------------------------------------------------------------------------- 1 | #include "../../src/VersionLib.huff" 2 | 3 | #define macro MAIN() = takes(0) returns(0) { 4 | GET_VERSION_VIEW() 5 | msize 6 | mstore 7 | msize 8 | 0x0 9 | return 10 | } 11 | -------------------------------------------------------------------------------- /test/utils/Create2Constants.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.0; 3 | 4 | bytes constant FACTORY_CODE = 5 | hex"60806040526004361061003f5760003560e01c806308508b8f1461004457806364e030871461009857806385cf97ab14610138578063a49a7c90146101bc575b600080fd5b34801561005057600080fd5b506100846004803603602081101561006757600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166101ec565b604080519115158252519081900360200190f35b61010f600480360360408110156100ae57600080fd5b813591908101906040810160208201356401000000008111156100d057600080fd5b8201836020820111156100e257600080fd5b8035906020019184600183028401116401000000008311171561010457600080fd5b509092509050610217565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561014457600080fd5b5061010f6004803603604081101561015b57600080fd5b8135919081019060408101602082013564010000000081111561017d57600080fd5b82018360208201111561018f57600080fd5b803590602001918460018302840111640100000000831117156101b157600080fd5b509092509050610592565b3480156101c857600080fd5b5061010f600480360360408110156101df57600080fd5b508035906020013561069e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205460ff1690565b600083606081901c33148061024c57507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008116155b6102a1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260458152602001806107746045913960600191505060405180910390fd5b606084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250604051855195965090943094508b93508692506020918201918291908401908083835b6020831061033557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016102f8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260408051929094018281037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00183528085528251928201929092207fff000000000000000000000000000000000000000000000000000000000000008383015260609890981b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602183015260358201969096526055808201979097528251808203909701875260750182525084519484019490942073ffffffffffffffffffffffffffffffffffffffff81166000908152938490529390922054929350505060ff16156104a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180610735603f913960400191505060405180910390fd5b81602001825188818334f5955050508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461053a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260468152602001806107b96046913960600191505060405180910390fd5b50505073ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790559392505050565b6000308484846040516020018083838082843760408051919093018181037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001825280845281516020928301207fff000000000000000000000000000000000000000000000000000000000000008383015260609990991b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166021820152603581019790975260558088019890985282518088039098018852607590960182525085519585019590952073ffffffffffffffffffffffffffffffffffffffff81166000908152948590529490932054939450505060ff909116159050610697575060005b9392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091523060601b6021830152603582018590526055808301859052835180840390910181526075909201835281519181019190912073ffffffffffffffffffffffffffffffffffffffff81166000908152918290529190205460ff161561072e575060005b9291505056fe496e76616c696420636f6e7472616374206372656174696f6e202d20636f6e74726163742068617320616c7265616479206265656e206465706c6f7965642e496e76616c69642073616c74202d206669727374203230206279746573206f66207468652073616c74206d757374206d617463682063616c6c696e6720616464726573732e4661696c656420746f206465706c6f7920636f6e7472616374207573696e672070726f76696465642073616c7420616e6420696e697469616c697a6174696f6e20636f64652ea265627a7a723058202bdc55310d97c4088f18acf04253db593f0914059f0c781a9df3624dcef0d1cf64736f6c634300050a0032"; 6 | 7 | address constant FACTORY_ADDR = 0x0000000000FFe8B47B3e2130213B802212439497; 8 | --------------------------------------------------------------------------------