Source Code
Overview
DEV Balance
0 DEV
More Info
ContractCreator
Multichain Info
N/A
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deploy Create2 | 7787197 | 199 days ago | IN | 0 DEV | 0.00027578 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
7787197 | 199 days ago | Contract Creation | 0 DEV |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
CreateX
Compiler Version
v0.8.23+commit.f704f362
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.8.23; /** * @title CreateX Factory Smart Contract * @author pcaversaccio (https://web.archive.org/web/20230921103111/https://pcaversaccio.com/) * @custom:coauthor Matt Solomon (https://web.archive.org/web/20230921103335/https://mattsolomon.dev/) * @notice Factory smart contract to make easier and safer usage of the * `CREATE` (https://web.archive.org/web/20230921103540/https://www.evm.codes/#f0?fork=shanghai) and `CREATE2` * (https://web.archive.org/web/20230921103540/https://www.evm.codes/#f5?fork=shanghai) EVM opcodes as well as of * `CREATE3`-based (https://web.archive.org/web/20230921103920/https://github.com/ethereum/EIPs/pull/3171) contract creations. * @dev To simplify testing of non-public variables and functions, we use the `internal` * function visibility specifier `internal` for all variables and functions, even though * they could technically be `private` since we do not expect anyone to inherit from * the `CreateX` contract. * @custom:security-contact See https://web.archive.org/web/20230921105029/https://raw.githubusercontent.com/pcaversaccio/createx/main/SECURITY.md. */ contract CreateX { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* IMMUTABLES */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Caches the contract address at construction, to be used for the custom errors. */ address internal immutable _SELF = address(this); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* TYPES */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Struct for the `payable` amounts in a deploy-and-initialise call. */ struct Values { uint256 constructorAmount; uint256 initCallAmount; } /** * @dev Enum for the selection of a permissioned deploy protection. */ enum SenderBytes { MsgSender, ZeroAddress, Random } /** * @dev Enum for the selection of a cross-chain redeploy protection. */ enum RedeployProtectionFlag { True, False, Unspecified } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Event that is emitted when a contract is successfully created. * @param newContract The address of the new contract. * @param salt The 32-byte random value used to create the contract address. */ event ContractCreation(address indexed newContract, bytes32 indexed salt); /** * @dev Event that is emitted when a contract is successfully created. * @param newContract The address of the new contract. */ event ContractCreation(address indexed newContract); /** * @dev Event that is emitted when a `CREATE3` proxy contract is successfully created. * @param newContract The address of the new proxy contract. * @param salt The 32-byte random value used to create the proxy address. */ event Create3ProxyContractCreation(address indexed newContract, bytes32 indexed salt); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Error that occurs when the contract creation failed. * @param emitter The contract that emits the error. */ error FailedContractCreation(address emitter); /** * @dev Error that occurs when the contract initialisation call failed. * @param emitter The contract that emits the error. * @param revertData The data returned by the failed initialisation call. */ error FailedContractInitialisation(address emitter, bytes revertData); /** * @dev Error that occurs when the salt value is invalid. * @param emitter The contract that emits the error. */ error InvalidSalt(address emitter); /** * @dev Error that occurs when the nonce value is invalid. * @param emitter The contract that emits the error. */ error InvalidNonceValue(address emitter); /** * @dev Error that occurs when transferring ether has failed. * @param emitter The contract that emits the error. * @param revertData The data returned by the failed ether transfer. */ error FailedEtherTransfer(address emitter, bytes revertData); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CREATE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Deploys a new contract via calling the `CREATE` opcode and using the creation * bytecode `initCode` and `msg.value` as inputs. In order to save deployment costs, * we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, * `initCode` must have a `payable` constructor. * @param initCode The creation bytecode. * @return newContract The 20-byte address where the contract was deployed. */ function deployCreate(bytes memory initCode) public payable returns (address newContract) { assembly ("memory-safe") { newContract := create(callvalue(), add(initCode, 0x20), mload(initCode)) } _requireSuccessfulContractCreation({newContract: newContract}); emit ContractCreation({newContract: newContract}); } /** * @dev Deploys and initialises a new contract via calling the `CREATE` opcode and using the * creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` * amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. In order to * save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` * is non-zero, `initCode` must have a `payable` constructor. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @param refundAddress The 20-byte address where any excess ether is returned to. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreateAndInit( bytes memory initCode, bytes memory data, Values memory values, address refundAddress ) public payable returns (address newContract) { assembly ("memory-safe") { newContract := create(mload(values), add(initCode, 0x20), mload(initCode)) } _requireSuccessfulContractCreation({newContract: newContract}); emit ContractCreation({newContract: newContract}); (bool success, bytes memory returnData) = newContract.call{value: values.initCallAmount}(data); if (!success) { revert FailedContractInitialisation({emitter: _SELF, revertData: returnData}); } if (_SELF.balance != 0) { // Any wei amount previously forced into this contract (e.g. by using the `SELFDESTRUCT` // opcode) will be part of the refund transaction. (success, returnData) = refundAddress.call{value: _SELF.balance}(""); if (!success) { revert FailedEtherTransfer({emitter: _SELF, revertData: returnData}); } } } /** * @dev Deploys and initialises a new contract via calling the `CREATE` opcode and using the * creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` * amounts `values`, and `msg.value` as inputs. In order to save deployment costs, we do not * sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, * `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreateAndInit( bytes memory initCode, bytes memory data, Values memory values ) public payable returns (address newContract) { newContract = deployCreateAndInit({initCode: initCode, data: data, values: values, refundAddress: msg.sender}); } /** * @dev Deploys a new EIP-1167 minimal proxy contract using the `CREATE` opcode, and initialises * the implementation contract using the implementation address `implementation`, the initialisation * code `data`, and `msg.value` as inputs. Note that if `msg.value` is non-zero, the initialiser * function called via `data` must be `payable`. * @param implementation The 20-byte implementation contract address. * @param data The initialisation code that is passed to the deployed proxy contract. * @return proxy The 20-byte address where the clone was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreateClone(address implementation, bytes memory data) public payable returns (address proxy) { bytes20 implementationInBytes = bytes20(implementation); assembly ("memory-safe") { let clone := mload(0x40) mstore( clone, hex"3d_60_2d_80_60_0a_3d_39_81_f3_36_3d_3d_37_3d_3d_3d_36_3d_73_00_00_00_00_00_00_00_00_00_00_00_00" ) mstore(add(clone, 0x14), implementationInBytes) mstore( add(clone, 0x28), hex"5a_f4_3d_82_80_3e_90_3d_91_60_2b_57_fd_5b_f3_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00" ) proxy := create(0, clone, 0x37) } if (proxy == address(0)) { revert FailedContractCreation({emitter: _SELF}); } emit ContractCreation({newContract: proxy}); (bool success, bytes memory returnData) = proxy.call{value: msg.value}(data); _requireSuccessfulContractInitialisation({ success: success, returnData: returnData, implementation: implementation }); } /** * @dev Returns the address where a contract will be stored if deployed via `deployer` using * the `CREATE` opcode. For the specification of the Recursive Length Prefix (RLP) encoding * scheme, please refer to p. 19 of the Ethereum Yellow Paper (https://web.archive.org/web/20230921110603/https://ethereum.github.io/yellowpaper/paper.pdf) * and the Ethereum Wiki (https://web.archive.org/web/20230921112807/https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/). * For further insights also, see the following issue: https://web.archive.org/web/20230921112943/https://github.com/transmissions11/solmate/issues/207. * * Based on the EIP-161 (https://web.archive.org/web/20230921113207/https://raw.githubusercontent.com/ethereum/EIPs/master/EIPS/eip-161.md) specification, * all contract accounts on the Ethereum mainnet are initiated with `nonce = 1`. Thus, the * first contract address created by another contract is calculated with a non-zero nonce. * @param deployer The 20-byte deployer address. * @param nonce The next 32-byte nonce of the deployer address. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreateAddress(address deployer, uint256 nonce) public view returns (address computedAddress) { bytes memory data; bytes1 len = bytes1(0x94); // The theoretical allowed limit, based on EIP-2681, for an account nonce is 2**64-2: // https://web.archive.org/web/20230921113252/https://eips.ethereum.org/EIPS/eip-2681. if (nonce > type(uint64).max - 1) { revert InvalidNonceValue({emitter: _SELF}); } // The integer zero is treated as an empty byte string and therefore has only one length prefix, // 0x80, which is calculated via 0x80 + 0. if (nonce == 0x00) { data = abi.encodePacked(bytes1(0xd6), len, deployer, bytes1(0x80)); } // A one-byte integer in the [0x00, 0x7f] range uses its own value as a length prefix, there is no // additional "0x80 + length" prefix that precedes it. else if (nonce <= 0x7f) { data = abi.encodePacked(bytes1(0xd6), len, deployer, uint8(nonce)); } // In the case of `nonce > 0x7f` and `nonce <= type(uint8).max`, we have the following encoding scheme // (the same calculation can be carried over for higher nonce bytes): // 0xda = 0xc0 (short RLP prefix) + 0x1a (= the bytes length of: 0x94 + address + 0x84 + nonce, in hex), // 0x94 = 0x80 + 0x14 (= the bytes length of an address, 20 bytes, in hex), // 0x84 = 0x80 + 0x04 (= the bytes length of the nonce, 4 bytes, in hex). else if (nonce <= type(uint8).max) { data = abi.encodePacked(bytes1(0xd7), len, deployer, bytes1(0x81), uint8(nonce)); } else if (nonce <= type(uint16).max) { data = abi.encodePacked(bytes1(0xd8), len, deployer, bytes1(0x82), uint16(nonce)); } else if (nonce <= type(uint24).max) { data = abi.encodePacked(bytes1(0xd9), len, deployer, bytes1(0x83), uint24(nonce)); } else if (nonce <= type(uint32).max) { data = abi.encodePacked(bytes1(0xda), len, deployer, bytes1(0x84), uint32(nonce)); } else if (nonce <= type(uint40).max) { data = abi.encodePacked(bytes1(0xdb), len, deployer, bytes1(0x85), uint40(nonce)); } else if (nonce <= type(uint48).max) { data = abi.encodePacked(bytes1(0xdc), len, deployer, bytes1(0x86), uint48(nonce)); } else if (nonce <= type(uint56).max) { data = abi.encodePacked(bytes1(0xdd), len, deployer, bytes1(0x87), uint56(nonce)); } else { data = abi.encodePacked(bytes1(0xde), len, deployer, bytes1(0x88), uint64(nonce)); } computedAddress = address(uint160(uint256(keccak256(data)))); } /** * @dev Returns the address where a contract will be stored if deployed via this contract * using the `CREATE` opcode. For the specification of the Recursive Length Prefix (RLP) * encoding scheme, please refer to p. 19 of the Ethereum Yellow Paper (https://web.archive.org/web/20230921110603/https://ethereum.github.io/yellowpaper/paper.pdf) * and the Ethereum Wiki (https://web.archive.org/web/20230921112807/https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/). * For further insights also, see the following issue: https://web.archive.org/web/20230921112943/https://github.com/transmissions11/solmate/issues/207. * * Based on the EIP-161 (https://web.archive.org/web/20230921113207/https://raw.githubusercontent.com/ethereum/EIPs/master/EIPS/eip-161.md) specification, * all contract accounts on the Ethereum mainnet are initiated with `nonce = 1`. Thus, the * first contract address created by another contract is calculated with a non-zero nonce. * @param nonce The next 32-byte nonce of this contract. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreateAddress(uint256 nonce) public view returns (address computedAddress) { computedAddress = computeCreateAddress({deployer: _SELF, nonce: nonce}); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CREATE2 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Deploys a new contract via calling the `CREATE2` opcode and using the salt value `salt`, * the creation bytecode `initCode`, and `msg.value` as inputs. In order to save deployment costs, * we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` * must have a `payable` constructor. * @param salt The 32-byte random value used to create the contract address. * @param initCode The creation bytecode. * @return newContract The 20-byte address where the contract was deployed. */ function deployCreate2(bytes32 salt, bytes memory initCode) public payable returns (address newContract) { bytes32 guardedSalt = _guard({salt: salt}); assembly ("memory-safe") { newContract := create2(callvalue(), add(initCode, 0x20), mload(initCode), guardedSalt) } _requireSuccessfulContractCreation({newContract: newContract}); emit ContractCreation({newContract: newContract, salt: guardedSalt}); } /** * @dev Deploys a new contract via calling the `CREATE2` opcode and using the creation bytecode * `initCode` and `msg.value` as inputs. The salt value is calculated pseudo-randomly using a * diverse selection of block and transaction properties. This approach does not guarantee true * randomness! In order to save deployment costs, we do not sanity check the `initCode` length. * Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor. * @param initCode The creation bytecode. * @return newContract The 20-byte address where the contract was deployed. */ function deployCreate2(bytes memory initCode) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate2`. newContract = deployCreate2({salt: _generateSalt(), initCode: initCode}); } /** * @dev Deploys and initialises a new contract via calling the `CREATE2` opcode and using the * salt value `salt`, the creation bytecode `initCode`, the initialisation code `data`, the struct * for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. * In order to save deployment costs, we do not sanity check the `initCode` length. Note that if * `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor. * @param salt The 32-byte random value used to create the contract address. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @param refundAddress The 20-byte address where any excess ether is returned to. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2AndInit( bytes32 salt, bytes memory initCode, bytes memory data, Values memory values, address refundAddress ) public payable returns (address newContract) { bytes32 guardedSalt = _guard({salt: salt}); assembly ("memory-safe") { newContract := create2(mload(values), add(initCode, 0x20), mload(initCode), guardedSalt) } _requireSuccessfulContractCreation({newContract: newContract}); emit ContractCreation({newContract: newContract, salt: guardedSalt}); (bool success, bytes memory returnData) = newContract.call{value: values.initCallAmount}(data); if (!success) { revert FailedContractInitialisation({emitter: _SELF, revertData: returnData}); } if (_SELF.balance != 0) { // Any wei amount previously forced into this contract (e.g. by using the `SELFDESTRUCT` // opcode) will be part of the refund transaction. (success, returnData) = refundAddress.call{value: _SELF.balance}(""); if (!success) { revert FailedEtherTransfer({emitter: _SELF, revertData: returnData}); } } } /** * @dev Deploys and initialises a new contract via calling the `CREATE2` opcode and using the * salt value `salt`, creation bytecode `initCode`, the initialisation code `data`, the struct for * the `payable` amounts `values`, and `msg.value` as inputs. In order to save deployment costs, * we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, * `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`. * @param salt The 32-byte random value used to create the contract address. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2AndInit( bytes32 salt, bytes memory initCode, bytes memory data, Values memory values ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate2AndInit`. newContract = deployCreate2AndInit({ salt: salt, initCode: initCode, data: data, values: values, refundAddress: msg.sender }); } /** * @dev Deploys and initialises a new contract via calling the `CREATE2` opcode and using the * creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` * amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. The salt value * is calculated pseudo-randomly using a diverse selection of block and transaction properties. * This approach does not guarantee true randomness! In order to save deployment costs, we do not * sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` * must have a `payable` constructor. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @param refundAddress The 20-byte address where any excess ether is returned to. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2AndInit( bytes memory initCode, bytes memory data, Values memory values, address refundAddress ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate2AndInit`. newContract = deployCreate2AndInit({ salt: _generateSalt(), initCode: initCode, data: data, values: values, refundAddress: refundAddress }); } /** * @dev Deploys and initialises a new contract via calling the `CREATE2` opcode and using the * creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts * `values`, and `msg.value` as inputs. The salt value is calculated pseudo-randomly using a * diverse selection of block and transaction properties. This approach does not guarantee true * randomness! In order to save deployment costs, we do not sanity check the `initCode` length. * Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, * and any excess ether is returned to `msg.sender`. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2AndInit( bytes memory initCode, bytes memory data, Values memory values ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate2AndInit`. newContract = deployCreate2AndInit({ salt: _generateSalt(), initCode: initCode, data: data, values: values, refundAddress: msg.sender }); } /** * @dev Deploys a new EIP-1167 minimal proxy contract using the `CREATE2` opcode and the salt * value `salt`, and initialises the implementation contract using the implementation address * `implementation`, the initialisation code `data`, and `msg.value` as inputs. Note that if * `msg.value` is non-zero, the initialiser function called via `data` must be `payable`. * @param salt The 32-byte random value used to create the proxy contract address. * @param implementation The 20-byte implementation contract address. * @param data The initialisation code that is passed to the deployed proxy contract. * @return proxy The 20-byte address where the clone was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2Clone( bytes32 salt, address implementation, bytes memory data ) public payable returns (address proxy) { bytes32 guardedSalt = _guard({salt: salt}); bytes20 implementationInBytes = bytes20(implementation); assembly ("memory-safe") { let clone := mload(0x40) mstore( clone, hex"3d_60_2d_80_60_0a_3d_39_81_f3_36_3d_3d_37_3d_3d_3d_36_3d_73_00_00_00_00_00_00_00_00_00_00_00_00" ) mstore(add(clone, 0x14), implementationInBytes) mstore( add(clone, 0x28), hex"5a_f4_3d_82_80_3e_90_3d_91_60_2b_57_fd_5b_f3_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00" ) proxy := create2(0, clone, 0x37, guardedSalt) } if (proxy == address(0)) { revert FailedContractCreation({emitter: _SELF}); } emit ContractCreation({newContract: proxy, salt: guardedSalt}); (bool success, bytes memory returnData) = proxy.call{value: msg.value}(data); _requireSuccessfulContractInitialisation({ success: success, returnData: returnData, implementation: implementation }); } /** * @dev Deploys a new EIP-1167 minimal proxy contract using the `CREATE2` opcode and the salt * value `salt`, and initialises the implementation contract using the implementation address * `implementation`, the initialisation code `data`, and `msg.value` as inputs. The salt value is * calculated pseudo-randomly using a diverse selection of block and transaction properties. This * approach does not guarantee true randomness! Note that if `msg.value` is non-zero, the initialiser * function called via `data` must be `payable`. * @param implementation The 20-byte implementation contract address. * @param data The initialisation code that is passed to the deployed proxy contract. * @return proxy The 20-byte address where the clone was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate2Clone(address implementation, bytes memory data) public payable returns (address proxy) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate2Clone`. proxy = deployCreate2Clone({salt: _generateSalt(), implementation: implementation, data: data}); } /** * @dev Returns the address where a contract will be stored if deployed via `deployer` using * the `CREATE2` opcode. Any change in the `initCodeHash` or `salt` values will result in a new * destination address. This implementation is based on OpenZeppelin: * https://web.archive.org/web/20230921113703/https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/181d518609a9f006fcb97af63e6952e603cf100e/contracts/utils/Create2.sol. * @param salt The 32-byte random value used to create the contract address. * @param initCodeHash The 32-byte bytecode digest of the contract creation bytecode. * @param deployer The 20-byte deployer address. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreate2Address( bytes32 salt, bytes32 initCodeHash, address deployer ) public pure returns (address computedAddress) { assembly ("memory-safe") { // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | // |----------------------|---------------------------------------------------------------------------| // | initCodeHash | CCCCCCCCCCCCC...CC | // | salt | BBBBBBBBBBBBB...BB | // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA | // | 0xFF | FF | // |----------------------|---------------------------------------------------------------------------| // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC | // | keccak256(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ | let ptr := mload(0x40) mstore(add(ptr, 0x40), initCodeHash) mstore(add(ptr, 0x20), salt) mstore(ptr, deployer) let start := add(ptr, 0x0b) mstore8(start, 0xff) computedAddress := keccak256(start, 85) } } /** * @dev Returns the address where a contract will be stored if deployed via this contract using * the `CREATE2` opcode. Any change in the `initCodeHash` or `salt` values will result in a new * destination address. * @param salt The 32-byte random value used to create the contract address. * @param initCodeHash The 32-byte bytecode digest of the contract creation bytecode. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) public view returns (address computedAddress) { computedAddress = computeCreate2Address({salt: salt, initCodeHash: initCodeHash, deployer: _SELF}); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CREATE3 */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Deploys a new contract via employing the `CREATE3` pattern (i.e. without an initcode * factor) and using the salt value `salt`, the creation bytecode `initCode`, and `msg.value` * as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. * Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor. This * implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param salt The 32-byte random value used to create the proxy contract address. * @param initCode The creation bytecode. * @return newContract The 20-byte address where the contract was deployed. * @custom:security We strongly recommend implementing a permissioned deploy protection by setting * the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun * proxy deployments on other chains. */ function deployCreate3(bytes32 salt, bytes memory initCode) public payable returns (address newContract) { bytes32 guardedSalt = _guard({salt: salt}); bytes memory proxyChildBytecode = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3"; address proxy; assembly ("memory-safe") { proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), guardedSalt) } if (proxy == address(0)) { revert FailedContractCreation({emitter: _SELF}); } emit Create3ProxyContractCreation({newContract: proxy, salt: guardedSalt}); newContract = computeCreate3Address({salt: guardedSalt}); (bool success, ) = proxy.call{value: msg.value}(initCode); _requireSuccessfulContractCreation({success: success, newContract: newContract}); emit ContractCreation({newContract: newContract}); } /** * @dev Deploys a new contract via employing the `CREATE3` pattern (i.e. without an initcode * factor) and using the salt value `salt`, the creation bytecode `initCode`, and `msg.value` * as inputs. The salt value is calculated pseudo-randomly using a diverse selection of block * and transaction properties. This approach does not guarantee true randomness! In order to save * deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is * non-zero, `initCode` must have a `payable` constructor. This implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param initCode The creation bytecode. * @return newContract The 20-byte address where the contract was deployed. */ function deployCreate3(bytes memory initCode) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate3`. newContract = deployCreate3({salt: _generateSalt(), initCode: initCode}); } /** * @dev Deploys and initialises a new contract via employing the `CREATE3` pattern (i.e. without * an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, the * initialisation code `data`, the struct for the `payable` amounts `values`, the refund address * `refundAddress`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity * check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must * have a `payable` constructor. This implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param salt The 32-byte random value used to create the proxy contract address. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @param refundAddress The 20-byte address where any excess ether is returned to. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. * Furthermore, we strongly recommend implementing a permissioned deploy protection by setting * the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun * proxy deployments on other chains. */ function deployCreate3AndInit( bytes32 salt, bytes memory initCode, bytes memory data, Values memory values, address refundAddress ) public payable returns (address newContract) { bytes32 guardedSalt = _guard({salt: salt}); bytes memory proxyChildBytecode = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3"; address proxy; assembly ("memory-safe") { proxy := create2(0, add(proxyChildBytecode, 32), mload(proxyChildBytecode), guardedSalt) } if (proxy == address(0)) { revert FailedContractCreation({emitter: _SELF}); } emit Create3ProxyContractCreation({newContract: proxy, salt: guardedSalt}); newContract = computeCreate3Address({salt: guardedSalt}); (bool success, ) = proxy.call{value: values.constructorAmount}(initCode); _requireSuccessfulContractCreation({success: success, newContract: newContract}); emit ContractCreation({newContract: newContract}); bytes memory returnData; (success, returnData) = newContract.call{value: values.initCallAmount}(data); if (!success) { revert FailedContractInitialisation({emitter: _SELF, revertData: returnData}); } if (_SELF.balance != 0) { // Any wei amount previously forced into this contract (e.g. by using the `SELFDESTRUCT` // opcode) will be part of the refund transaction. (success, returnData) = refundAddress.call{value: _SELF.balance}(""); if (!success) { revert FailedEtherTransfer({emitter: _SELF, revertData: returnData}); } } } /** * @dev Deploys and initialises a new contract via employing the `CREATE3` pattern (i.e. without * an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, the * initialisation code `data`, the struct for the `payable` amounts `values`, and `msg.value` as * inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note * that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, * and any excess ether is returned to `msg.sender`. This implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param salt The 32-byte random value used to create the proxy contract address. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. * Furthermore, we strongly recommend implementing a permissioned deploy protection by setting * the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun * proxy deployments on other chains. */ function deployCreate3AndInit( bytes32 salt, bytes memory initCode, bytes memory data, Values memory values ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate3AndInit`. newContract = deployCreate3AndInit({ salt: salt, initCode: initCode, data: data, values: values, refundAddress: msg.sender }); } /** * @dev Deploys and initialises a new contract via employing the `CREATE3` pattern (i.e. without * an initcode factor) and using the creation bytecode `initCode`, the initialisation code `data`, * the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` * as inputs. The salt value is calculated pseudo-randomly using a diverse selection of block and * transaction properties. This approach does not guarantee true randomness! In order to save deployment * costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, * `initCode` must have a `payable` constructor. This implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @param refundAddress The 20-byte address where any excess ether is returned to. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate3AndInit( bytes memory initCode, bytes memory data, Values memory values, address refundAddress ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate3AndInit`. newContract = deployCreate3AndInit({ salt: _generateSalt(), initCode: initCode, data: data, values: values, refundAddress: refundAddress }); } /** * @dev Deploys and initialises a new contract via employing the `CREATE3` pattern (i.e. without * an initcode factor) and using the creation bytecode `initCode`, the initialisation code `data`, * the struct for the `payable` amounts `values`, `msg.value` as inputs. The salt value is calculated * pseudo-randomly using a diverse selection of block and transaction properties. This approach does * not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` * length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, * and any excess ether is returned to `msg.sender`. This implementation is based on Solmate: * https://web.archive.org/web/20230921113832/https://raw.githubusercontent.com/transmissions11/solmate/e8f96f25d48fe702117ce76c79228ca4f20206cb/src/utils/CREATE3.sol. * @param initCode The creation bytecode. * @param data The initialisation code that is passed to the deployed contract. * @param values The specific `payable` amounts for the deployment and initialisation call. * @return newContract The 20-byte address where the contract was deployed. * @custom:security This function allows for reentrancy, however we refrain from adding * a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol * level that potentially malicious reentrant calls do not affect your smart contract system. */ function deployCreate3AndInit( bytes memory initCode, bytes memory data, Values memory values ) public payable returns (address newContract) { // Note that the safeguarding function `_guard` is called as part of the overloaded function // `deployCreate3AndInit`. newContract = deployCreate3AndInit({ salt: _generateSalt(), initCode: initCode, data: data, values: values, refundAddress: msg.sender }); } /** * @dev Returns the address where a contract will be stored if deployed via `deployer` using * the `CREATE3` pattern (i.e. without an initcode factor). Any change in the `salt` value will * result in a new destination address. This implementation is based on Solady: * https://web.archive.org/web/20230921114120/https://raw.githubusercontent.com/Vectorized/solady/1c1ac4ad9c8558001e92d8d1a7722ef67bec75df/src/utils/CREATE3.sol. * @param salt The 32-byte random value used to create the proxy contract address. * @param deployer The 20-byte deployer address. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreate3Address(bytes32 salt, address deployer) public pure returns (address computedAddress) { assembly ("memory-safe") { let ptr := mload(0x40) mstore(0x00, deployer) mstore8(0x0b, 0xff) mstore(0x20, salt) mstore( 0x40, hex"21_c3_5d_be_1b_34_4a_24_88_cf_33_21_d6_ce_54_2f_8e_9f_30_55_44_ff_09_e4_99_3a_62_31_9a_49_7c_1f" ) mstore(0x14, keccak256(0x0b, 0x55)) mstore(0x40, ptr) mstore(0x00, 0xd694) mstore8(0x34, 0x01) computedAddress := keccak256(0x1e, 0x17) } } /** * @dev Returns the address where a contract will be stored if deployed via this contract using * the `CREATE3` pattern (i.e. without an initcode factor). Any change in the `salt` value will * result in a new destination address. This implementation is based on Solady: * https://web.archive.org/web/20230921114120/https://raw.githubusercontent.com/Vectorized/solady/1c1ac4ad9c8558001e92d8d1a7722ef67bec75df/src/utils/CREATE3.sol. * @param salt The 32-byte random value used to create the proxy contract address. * @return computedAddress The 20-byte address where a contract will be stored. */ function computeCreate3Address(bytes32 salt) public view returns (address computedAddress) { computedAddress = computeCreate3Address({salt: salt, deployer: _SELF}); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HELPER FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /** * @dev Implements different safeguarding mechanisms depending on the encoded values in the salt * (`||` stands for byte-wise concatenation): * => salt (32 bytes) = 0xbebebebebebebebebebebebebebebebebebebebe||ff||1212121212121212121212 * - The first 20 bytes (i.e. `bebebebebebebebebebebebebebebebebebebebe`) may be used to * implement a permissioned deploy protection by setting them equal to `msg.sender`, * - The 21st byte (i.e. `ff`) may be used to implement a cross-chain redeploy protection by * setting it equal to `0x01`, * - The last random 11 bytes (i.e. `1212121212121212121212`) allow for 2**88 bits of entropy * for mining a salt. * @param salt The 32-byte random value used to create the contract address. * @return guardedSalt The guarded 32-byte random value used to create the contract address. */ function _guard(bytes32 salt) internal view returns (bytes32 guardedSalt) { (SenderBytes senderBytes, RedeployProtectionFlag redeployProtectionFlag) = _parseSalt({salt: salt}); if (senderBytes == SenderBytes.MsgSender && redeployProtectionFlag == RedeployProtectionFlag.True) { // Configures a permissioned deploy protection as well as a cross-chain redeploy protection. guardedSalt = keccak256(abi.encode(msg.sender, block.chainid, salt)); } else if (senderBytes == SenderBytes.MsgSender && redeployProtectionFlag == RedeployProtectionFlag.False) { // Configures solely a permissioned deploy protection. guardedSalt = _efficientHash({a: bytes32(uint256(uint160(msg.sender))), b: salt}); } else if (senderBytes == SenderBytes.MsgSender) { // Reverts if the 21st byte is greater than `0x01` in order to enforce developer explicitness. revert InvalidSalt({emitter: _SELF}); } else if (senderBytes == SenderBytes.ZeroAddress && redeployProtectionFlag == RedeployProtectionFlag.True) { // Configures solely a cross-chain redeploy protection. In order to prevent a pseudo-randomly // generated cross-chain redeploy protection, we enforce the zero address check for the first 20 bytes. guardedSalt = _efficientHash({a: bytes32(block.chainid), b: salt}); } else if ( senderBytes == SenderBytes.ZeroAddress && redeployProtectionFlag == RedeployProtectionFlag.Unspecified ) { // Reverts if the 21st byte is greater than `0x01` in order to enforce developer explicitness. revert InvalidSalt({emitter: _SELF}); } else { // For the non-pseudo-random cases, the salt value `salt` is hashed to prevent the safeguard mechanisms // from being bypassed. Otherwise, the salt value `salt` is not modified. guardedSalt = (salt != _generateSalt()) ? keccak256(abi.encode(salt)) : salt; } } /** * @dev Returns the enum for the selection of a permissioned deploy protection as well as a * cross-chain redeploy protection. * @param salt The 32-byte random value used to create the contract address. * @return senderBytes The 8-byte enum for the selection of a permissioned deploy protection. * @return redeployProtectionFlag The 8-byte enum for the selection of a cross-chain redeploy * protection. */ function _parseSalt( bytes32 salt ) internal view returns (SenderBytes senderBytes, RedeployProtectionFlag redeployProtectionFlag) { if (address(bytes20(salt)) == msg.sender && bytes1(salt[20]) == hex"01") { (senderBytes, redeployProtectionFlag) = (SenderBytes.MsgSender, RedeployProtectionFlag.True); } else if (address(bytes20(salt)) == msg.sender && bytes1(salt[20]) == hex"00") { (senderBytes, redeployProtectionFlag) = (SenderBytes.MsgSender, RedeployProtectionFlag.False); } else if (address(bytes20(salt)) == msg.sender) { (senderBytes, redeployProtectionFlag) = (SenderBytes.MsgSender, RedeployProtectionFlag.Unspecified); } else if (address(bytes20(salt)) == address(0) && bytes1(salt[20]) == hex"01") { (senderBytes, redeployProtectionFlag) = (SenderBytes.ZeroAddress, RedeployProtectionFlag.True); } else if (address(bytes20(salt)) == address(0) && bytes1(salt[20]) == hex"00") { (senderBytes, redeployProtectionFlag) = (SenderBytes.ZeroAddress, RedeployProtectionFlag.False); } else if (address(bytes20(salt)) == address(0)) { (senderBytes, redeployProtectionFlag) = (SenderBytes.ZeroAddress, RedeployProtectionFlag.Unspecified); } else if (bytes1(salt[20]) == hex"01") { (senderBytes, redeployProtectionFlag) = (SenderBytes.Random, RedeployProtectionFlag.True); } else if (bytes1(salt[20]) == hex"00") { (senderBytes, redeployProtectionFlag) = (SenderBytes.Random, RedeployProtectionFlag.False); } else { (senderBytes, redeployProtectionFlag) = (SenderBytes.Random, RedeployProtectionFlag.Unspecified); } } /** * @dev Returns the `keccak256` hash of `a` and `b` after concatenation. * @param a The first 32-byte value to be concatenated and hashed. * @param b The second 32-byte value to be concatenated and hashed. * @return hash The 32-byte `keccak256` hash of `a` and `b`. */ function _efficientHash(bytes32 a, bytes32 b) internal pure returns (bytes32 hash) { assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) hash := keccak256(0x00, 0x40) } } /** * @dev Generates pseudo-randomly a salt value using a diverse selection of block and * transaction properties. * @return salt The 32-byte pseudo-random salt value. */ function _generateSalt() internal view returns (bytes32 salt) { unchecked { salt = keccak256( abi.encode( // We don't use `block.number - 256` (the maximum value on the EVM) to accommodate // any chains that may try to reduce the amount of available historical block hashes. // We also don't subtract 1 to mitigate any risks arising from consecutive block // producers on a PoS chain. Therefore, we use `block.number - 32` as a reasonable // compromise, one we expect should work on most chains, which is 1 epoch on Ethereum // mainnet. Please note that if you use this function between the genesis block and block // number 31, the block property `blockhash` will return zero, but the returned salt value // `salt` will still have a non-zero value due to the hashing characteristic and the other // remaining properties. blockhash(block.number - 32), block.coinbase, block.number, block.timestamp, block.prevrandao, block.chainid, msg.sender ) ); } } /** * @dev Ensures that `newContract` is a non-zero byte contract. * @param success The Boolean success condition. * @param newContract The 20-byte address where the contract was deployed. */ function _requireSuccessfulContractCreation(bool success, address newContract) internal view { // Note that reverting if `newContract == address(0)` isn't strictly necessary here, as if // the deployment fails, `success == false` should already hold. However, since the `CreateX` // contract should be usable and safe on a wide range of chains, this check is cheap enough // that there is no harm in including it (security > gas optimisations). It can potentially // protect against unexpected chain behaviour or a hypothetical compiler bug that doesn't surface // the call success status properly. if (!success || newContract == address(0) || newContract.code.length == 0) { revert FailedContractCreation({emitter: _SELF}); } } /** * @dev Ensures that `newContract` is a non-zero byte contract. * @param newContract The 20-byte address where the contract was deployed. */ function _requireSuccessfulContractCreation(address newContract) internal view { if (newContract == address(0) || newContract.code.length == 0) { revert FailedContractCreation({emitter: _SELF}); } } /** * @dev Ensures that the contract initialisation call to `implementation` has been successful. * @param success The Boolean success condition. * @param returnData The return data from the contract initialisation call. * @param implementation The 20-byte address where the implementation was deployed. */ function _requireSuccessfulContractInitialisation( bool success, bytes memory returnData, address implementation ) internal view { if (!success || implementation.code.length == 0) { revert FailedContractInitialisation({emitter: _SELF, revertData: returnData}); } } }
{ "optimizer": { "enabled": true, "runs": 10000000 }, "evmVersion": "paris", "viaIR": false, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"FailedContractCreation","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"bytes","name":"revertData","type":"bytes"}],"name":"FailedContractInitialisation","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"bytes","name":"revertData","type":"bytes"}],"name":"FailedEtherTransfer","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"InvalidNonceValue","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"InvalidSalt","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newContract","type":"address"},{"indexed":true,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"ContractCreation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newContract","type":"address"}],"name":"ContractCreation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newContract","type":"address"},{"indexed":true,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"Create3ProxyContractCreation","type":"event"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes32","name":"initCodeHash","type":"bytes32"}],"name":"computeCreate2Address","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes32","name":"initCodeHash","type":"bytes32"},{"internalType":"address","name":"deployer","type":"address"}],"name":"computeCreate2Address","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"deployer","type":"address"}],"name":"computeCreate3Address","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"computeCreate3Address","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"computeCreateAddress","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"deployer","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"computeCreateAddress","outputs":[{"internalType":"address","name":"computedAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"deployCreate","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"deployCreate2","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"deployCreate2","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"deployCreate2AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"}],"name":"deployCreate2AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"deployCreate2AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"}],"name":"deployCreate2AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"deployCreate2Clone","outputs":[{"internalType":"address","name":"proxy","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"deployCreate2Clone","outputs":[{"internalType":"address","name":"proxy","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"deployCreate3","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"}],"name":"deployCreate3","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"}],"name":"deployCreate3AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"}],"name":"deployCreate3AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"deployCreate3AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"deployCreate3AndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"}],"name":"deployCreateAndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initCode","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"constructorAmount","type":"uint256"},{"internalType":"uint256","name":"initCallAmount","type":"uint256"}],"internalType":"struct CreateX.Values","name":"values","type":"tuple"},{"internalType":"address","name":"refundAddress","type":"address"}],"name":"deployCreateAndInit","outputs":[{"internalType":"address","name":"newContract","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"deployCreateClone","outputs":[{"internalType":"address","name":"proxy","type":"address"}],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a06040523060805234801561001457600080fd5b50608051612e3e6100d860003960008181610603015281816107050152818161082b015281816108d50152818161127f01528181611375015281816113e00152818161141f015281816114a7015281816115b3015281816117d20152818161183d0152818161187c0152818161190401528181611ac501528181611c7801528181611ce301528181611d2201528181611daa01528181611fe901528181612206015281816122f20152818161244d015281816124a601526125820152612e3e6000f3fe60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f00000000000000000000000000000000000000000000000000000000000000008361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f00000000000000000000000000000000000000000000000000000000000000006107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f00000000000000000000000000000000000000000000000000000000000000006119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f0000000000000000000000000000000000000000000000000000000000000000826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a
Deployed Bytecode
0x60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed8361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a
Deployed Bytecode Sourcemap
1176:58382:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43057:537;;;;;;:::i;:::-;;:::i;:::-;;;2365:42:1;2353:55;;;2335:74;;2323:2;2308:18;43057:537:0;;;;;;;18043:458;;;;;;:::i;:::-;;:::i;19138:309::-;;;;;;:::i;:::-;;:::i;5773:358::-;;;;;;:::i;:::-;;:::i;28426:1274::-;;;;;;:::i;:::-;;:::i;17004:179::-;;;;;;;;;;-1:-1:-1;17004:179:0;;;;;:::i;:::-;;:::i;47277:526::-;;;;;;:::i;:::-;;:::i;9530:295::-;;;;;;:::i;:::-;;:::i;48496:663::-;;;;;;;;;;-1:-1:-1;48496:663:0;;;;;:::i;:::-;;:::i;49802:178::-;;;;;;;;;;-1:-1:-1;49802:178:0;;;;;:::i;:::-;;:::i;13113:2706::-;;;;;;;;;;-1:-1:-1;13113:2706:0;;;;;:::i;:::-;;:::i;37545:309::-;;;;;;:::i;:::-;;:::i;30801:356::-;;;;;;:::i;:::-;;:::i;34126:228::-;;;;;;;;;;-1:-1:-1;34126:228:0;;;;;:::i;:::-;;:::i;7308:1118::-;;;;;;:::i;:::-;;:::i;35725:902::-;;;;;;:::i;:::-;;:::i;20729:1226::-;;;;;;:::i;:::-;;:::i;26884:526::-;;;;;;:::i;:::-;;:::i;31948:1673::-;;;;;;;;;;-1:-1:-1;31948:1673:0;;;;;:::i;:::-;;:::i;39643:1698::-;;;;;;:::i;:::-;;:::i;25047:560::-;;;;;;:::i;:::-;;:::i;23160:537::-;;;;;;:::i;:::-;;:::i;45194:560::-;;;;;;:::i;:::-;;:::i;10727:1144::-;;;;;;:::i;:::-;;:::i;43057:537::-;43227:19;43408:179;43449:4;43477:8;43505:4;43531:6;43566:10;43408:20;:179::i;:::-;43394:193;43057:537;-1:-1:-1;;;;;43057:537:0:o;18043:458::-;18127:19;18158;18180:20;18194:4;18180:6;:20::i;:::-;18158:42;;18323:11;18312:8;18306:15;18299:4;18289:8;18285:19;18272:11;18264:71;18249:86;;18354:62;18403:11;18354:34;:62::i;:::-;18431:63;;18481:11;;18431:63;;;;;;;;;18148:353;18043:458;;;;:::o;19138:309::-;19208:19;19382:58;19403:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;19403:15;19430:8;19382:13;:58::i;:::-;19368:72;19138:309;-1:-1:-1;;19138:309:0:o;5773:358::-;5842:19;5974:8;5968:15;5961:4;5951:8;5947:19;5934:11;5927:57;5912:72;;6003:62;6052:11;6003:34;:62::i;:::-;6080:44;;;;;;;;;;;5773:358;;;:::o;28426:1274::-;28565:13;28590:19;28612:20;28626:4;28612:6;:20::i;:::-;28590:42;;28642:29;28682:14;28674:23;;28642:55;;28765:4;28759:11;28830:100;28807:5;28783:161;28982:21;28975:4;28968:5;28964:16;28957:47;29075:100;29052:4;29045:5;29041:16;29017:172;29235:11;29229:4;29222:5;29219:1;29211:36;29202:45;-1:-1:-1;;29270:19:0;;;29266:97;;29312:40;;;;;2365:42:1;29345:5:0;2353:55:1;29312:40:0;;;2335:74:1;2308:18;;29312:40:0;;;;;;;;29266:97;29377:57;;29421:11;;29377:57;;;;;;;;;29446:12;29460:23;29487:5;:10;;29505:9;29516:4;29487:34;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29445:76;;;;29531:162;29595:7;29628:10;29668:14;29531:40;:162::i;:::-;28580:1120;;;;28426:1274;;;;;:::o;17004:179::-;17070:23;17123:53;17155:5;17169;17123:20;:53::i;47277:526::-;47425:19;47606:190;47647:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;47647:15;47686:8;47714:4;47740:6;47775:10;47606:20;:190::i;:::-;47592:204;47277:526;-1:-1:-1;;;;47277:526:0:o;9530:295::-;9677:19;9722:96;9753:8;9769:4;9783:6;9806:10;9722:19;:96::i;48496:663::-;48580:23;48671:4;48665:11;48702:8;48696:4;48689:22;48738:4;48732;48724:19;48769:4;48763;48756:18;48833:100;48811:4;48787:160;48989:4;48983;48973:21;48967:4;48960:35;49021:3;49015:4;49008:17;;49051:6;49045:4;49038:20;49085:4;49079;49071:19;-1:-1:-1;;49138:4:0;49132;49122:21;;48496:663;-1:-1:-1;48496:663:0:o;49802:178::-;49868:23;49921:52;49950:4;49966:5;49921:21;:52::i;13113:2706::-;13197:23;13232:17;13272:12;13496:20;13515:1;13496:16;:20;:::i;:::-;13488:28;;:5;:28;13484:101;;;13539:35;;;;;2365:42:1;13567:5:0;2353:55:1;13539:35:0;;;2335:74:1;2308:18;;13539:35:0;2189:226:1;13484:101:0;13755:5;13764:4;13755:13;13751:1991;;13791:59;;13808:12;13791:59;;;9040:28:1;8965:66;9097:15;;9084:11;;;9077:36;9163:66;9150:2;9146:15;;;9142:88;9129:11;;;9122:109;13837:12:0;9247::1;;;9240:37;9293:12;;13791:59:0;;;;;;;;;;;;;13784:66;;13751:1991;;;14058:4;14049:5;:13;14045:1697;;14085:59;;14102:12;14085:59;;;9606:28:1;9531:66;9663:15;;;9650:11;;;9643:36;9729:66;9716:2;9712:15;;;9708:88;9695:11;;;9688:109;9835:3;9831:16;;;9827:25;9813:12;;;9806:47;9869:12;;14085:59:0;9316:571:1;14045:1697:0;14650:15;14641:24;;14637:1105;;14688:73;;14705:12;14688:73;;;10208:28:1;10133:66;10265:15;;;10252:11;;;10245:36;10331:66;10318:2;10314:15;;;10310:88;10297:11;;;10290:109;14734:12:0;10415::1;;;10408:37;10483:3;10479:16;;;10475:25;10461:12;;;10454:47;10517:12;;14688:73:0;9892:643:1;14637:1105:0;14791:16;14782:25;;14778:964;;14830:74;;14847:12;14830:74;;;10858:28:1;10783:66;10915:15;;10902:11;;;10895:36;10981:66;10968:2;10964:15;;;10960:88;10947:11;;;10940:109;14876:12:0;11065::1;;;11058:37;11147:66;11133:3;11129:16;;;11125:89;11111:12;;;11104:111;11231:12;;14830:74:0;10540:709:1;14778:964:0;14934:16;14925:25;;14921:821;;14973:74;;14990:12;14973:74;;;11572:28:1;11497:66;11629:15;;11616:11;;;11609:36;11695:66;11682:2;11678:15;;;11674:88;11661:11;;;11654:109;15019:12:0;11779::1;;;11772:37;11861:66;11847:3;11843:16;;;11839:89;11825:12;;;11818:111;11945:12;;14973:74:0;11254:709:1;14921:821:0;15077:16;15068:25;;15064:678;;15116:74;;15133:12;15116:74;;;12286:28:1;12211:66;12343:15;;12330:11;;;12323:36;12409:66;12396:2;12392:15;;;12388:88;12375:11;;;12368:109;15162:12:0;12493::1;;;12486:37;12575:66;12561:3;12557:16;;;12553:89;12539:12;;;12532:111;12659:12;;15116:74:0;11968:709:1;15064:678:0;15220:16;15211:25;;15207:535;;15259:74;;15276:12;15259:74;;;13000:28:1;12925:66;13057:15;;13044:11;;;13037:36;13123:66;13110:2;13106:15;;;13102:88;13089:11;;;13082:109;15305:12:0;13207::1;;;13200:37;13289:66;13275:3;13271:16;;;13267:89;13253:12;;;13246:111;13373:12;;15259:74:0;12682:709:1;15207:535:0;15363:16;15354:25;;15350:392;;15402:74;;15419:12;15402:74;;;13714:28:1;13639:66;13771:15;;13758:11;;;13751:36;13837:66;13824:2;13820:15;;;13816:88;13803:11;;;13796:109;15448:12:0;13921::1;;;13914:37;14003:66;13989:3;13985:16;;;13981:89;13967:12;;;13960:111;14087:12;;15402:74:0;13396:709:1;15350:392:0;15506:16;15497:25;;15493:249;;15545:74;;15562:12;15545:74;;;14428:28:1;14353:66;14485:15;;14472:11;;;14465:36;14551:66;14538:2;14534:15;;;14530:88;14517:11;;;14510:109;15591:12:0;14635::1;;;14628:37;14717:66;14703:3;14699:16;;;14695:89;14681:12;;;14674:111;14801:12;;15545:74:0;14110:709:1;15493:249:0;15657:74;;15674:12;15657:74;;;15142:28:1;15067:66;15199:15;;15186:11;;;15179:36;15265:66;15252:2;15248:15;;;15244:88;15231:11;;;15224:109;15703:12:0;15349::1;;;15342:37;15431:66;15417:3;15413:16;;;15409:89;15395:12;;;15388:111;15515:12;;15657:74:0;;;;;;;;;;;;15650:81;;15493:249;-1:-1:-1;15794:15:0;;;;;;;;13113:2706;-1:-1:-1;;;13113:2706:0:o;37545:309::-;37615:19;37789:58;37810:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;37810:15;37837:8;37789:13;:58::i;30801:356::-;30896:13;31063:87;31089:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;31089:15;31122:14;31144:4;31063:18;:87::i;:::-;31055:95;30801:356;-1:-1:-1;;;30801:356:0:o;34126:228::-;34214:23;34267:80;34296:4;34316:12;34340:5;34267:21;:80::i;7308:1118::-;7486:19;7620:8;7614:15;7607:4;7597:8;7593:19;7584:6;7578:13;7571:59;7556:74;;7649:62;7698:11;7649:34;:62::i;:::-;7726:44;;;;;;;;;;;7782:12;7796:23;7823:11;:16;;7847:6;:21;;;7870:4;7823:52;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7781:94;;;;7890:7;7885:116;;7959:5;7978:10;7920:70;;;;;;;;;;;;:::i;7885:116::-;8015:13;:5;:13;;:18;8011:409;;8237:13;:18;;8263:5;:13;;;8237:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8213:68:0;;-1:-1:-1;8213:68:0;-1:-1:-1;8213:68:0;8295:115;;8364:5;8383:10;8334:61;;;;;;;;;;;;:::i;8295:115::-;7507:919;;7308:1118;;;;;;:::o;35725:902::-;35809:19;35840;35862:20;35876:4;35862:6;:20::i;:::-;35840:42;;35892:31;:86;;;;;;;;;;;;;;;;;;;35988:13;36126:11;36105:18;36099:25;36094:2;36074:18;36070:27;36067:1;36059:79;36050:88;-1:-1:-1;36161:19:0;;;36157:97;;36203:40;;;;;2365:42:1;36236:5:0;2353:55:1;36203:40:0;;;2335:74:1;2308:18;;36203:40:0;2189:226:1;36157:97:0;36268:69;;36324:11;;36268:69;;;;;;;;;36362:42;36391:11;36362:21;:42::i;:::-;36348:56;;36415:12;36433:5;:10;;36451:9;36462:8;36433:38;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36414:57;;;36481:80;36526:7;36548:11;36481:34;:80::i;:::-;36576:44;;;;;;;;;;;35830:797;;;;35725:902;;;;:::o;20729:1226::-;20930:19;20961;20983:20;20997:4;20983:6;:20::i;:::-;20961:42;;21128:11;21117:8;21111:15;21104:4;21094:8;21090:19;21081:6;21075:13;21067:73;21052:88;;21159:62;21208:11;21159:34;:62::i;:::-;21236:63;;21286:11;;21236:63;;;;;;;;;21311:12;21325:23;21352:11;:16;;21376:6;:21;;;21399:4;21352:52;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21310:94;;;;21419:7;21414:116;;21488:5;21507:10;21449:70;;;;;;;;;;;;:::i;21414:116::-;21544:13;:5;:13;;:18;21540:409;;21766:13;:18;;21792:5;:13;;;21766:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21742:68:0;;-1:-1:-1;21742:68:0;-1:-1:-1;21742:68:0;21824:115;;21893:5;21912:10;21863:61;;;;;;;;;;;;:::i;21824:115::-;20951:1004;;;20729:1226;;;;;;;:::o;26884:526::-;27032:19;27213:190;27254:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;27254:15;27293:8;27321:4;27347:6;27382:10;27213:20;:190::i;31948:1673::-;32084:23;33351:4;33345:11;33392:12;33385:4;33380:3;33376:14;33369:36;33441:4;33434;33429:3;33425:14;33418:28;33471:8;33466:3;33459:21;33515:4;33510:3;33506:14;33493:27;;33548:4;33541:5;33533:20;33602:2;33585:20;;;31948:1673;-1:-1:-1;;;;31948:1673:0:o;39643:1698::-;39844:19;39875;39897:20;39911:4;39897:6;:20::i;:::-;39875:42;;39927:31;:86;;;;;;;;;;;;;;;;;;;40023:13;40161:11;40140:18;40134:25;40129:2;40109:18;40105:27;40102:1;40094:79;40085:88;-1:-1:-1;40196:19:0;;;40192:97;;40238:40;;;;;2365:42:1;40271:5:0;2353:55:1;40238:40:0;;;2335:74:1;2308:18;;40238:40:0;2189:226:1;40192:97:0;40303:69;;40359:11;;40303:69;;;;;;;;;40397:42;40426:11;40397:21;:42::i;:::-;40383:56;;40450:12;40468:5;:10;;40486:6;:24;;;40512:8;40468:53;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40449:72;;;40531:80;40576:7;40598:11;40531:34;:80::i;:::-;40626:44;;;;;;;;;;;40681:23;40738:11;:16;;40762:6;:21;;;40785:4;40738:52;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40714:76:0;;-1:-1:-1;40714:76:0;-1:-1:-1;40714:76:0;40800:116;;40874:5;40893:10;40835:70;;;;;;;;;;;;:::i;40800:116::-;40930:13;:5;:13;;:18;40926:409;;41152:13;:18;;41178:5;:13;;;41152:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41128:68:0;;-1:-1:-1;41128:68:0;-1:-1:-1;41128:68:0;41210:115;;41279:5;41298:10;41249:61;;;;;;;;;;;;:::i;41210:115::-;39865:1476;;;;;39643:1698;;;;;;;:::o;25047:560::-;25226:19;25407:193;25448:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;25448:15;25487:8;25515:4;25541:6;25576:13;25407:20;:193::i;23160:537::-;23330:19;23511:179;23552:4;23580:8;23608:4;23634:6;23669:10;23511:20;:179::i;45194:560::-;45373:19;45554:193;45595:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;45595:15;45634:8;45662:4;45688:6;45723:13;45554:20;:193::i;10727:1144::-;10821:13;10846:29;10886:14;10878:23;;10846:55;;10969:4;10963:11;11034:100;11011:5;10987:161;11186:21;11179:4;11172:5;11168:16;11161:47;11279:100;11256:4;11249:5;11245:16;11221:172;11432:4;11425:5;11422:1;11415:22;11406:31;-1:-1:-1;;11460:19:0;;;11456:97;;11502:40;;;;;2365:42:1;11535:5:0;2353:55:1;11502:40:0;;;2335:74:1;2308:18;;11502:40:0;2189:226:1;11456:97:0;11567:38;;;;;;;;;;;11617:12;11631:23;11658:5;:10;;11676:9;11687:4;11658:34;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11616:76;;;;11702:162;11766:7;11799:10;11839:14;11702:40;:162::i;:::-;10836:1035;;;10727:1144;;;;:::o;51171:2025::-;51224:19;51256:23;51281:45;51330:24;51348:4;51330:10;:24::i;:::-;51255:99;;-1:-1:-1;51255:99:0;-1:-1:-1;51384:21:0;51369:11;:36;;;;;;;;:::i;:::-;;:93;;;;-1:-1:-1;51435:27:0;51409:22;:53;;;;;;;;:::i;:::-;;51369:93;51365:1825;;;51607:43;;;51618:10;51607:43;;;16717:74:1;51630:13:0;16807:18:1;;;16800:34;;;;16850:18;;;16843:34;;;16690:18;;51607:43:0;;;;;;;;;;;;51597:54;;;;;;51583:68;;51365:1825;;;51687:21;51672:11;:36;;;;;;;;:::i;:::-;;:94;;;;-1:-1:-1;51738:28:0;51712:22;:54;;;;;;;;:::i;:::-;;51672:94;51668:1522;;;51863:67;51906:10;51924:4;55749:12;55812:15;;;55847:4;55840:15;55892:4;55876:21;;;55680:233;51863:67;51849:81;;51668:1522;;;51966:21;51951:11;:36;;;;;;;;:::i;:::-;;51947:1243;;52117:29;;;;;2365:42:1;52139:5:0;2353:55:1;52117:29:0;;;2335:74:1;2308:18;;52117:29:0;2189:226:1;51947:1243:0;52182:23;52167:11;:38;;;;;;;;:::i;:::-;;:95;;;;-1:-1:-1;52235:27:0;52209:22;:53;;;;;;;;:::i;:::-;;52167:95;52163:1027;;;52514:52;52541:13;52560:4;55749:12;55812:15;;;55847:4;55840:15;55892:4;55876:21;;;55680:233;52163:1027;52615:23;52600:11;:38;;;;;;;;:::i;:::-;;:102;;;;-1:-1:-1;52668:34:0;52642:22;:60;;;;;;;;:::i;:::-;;52600:102;52583:607;;;52841:29;;;;;2365:42:1;52863:5:0;2353:55:1;52841:29:0;;;2335:74:1;2308:18;;52841:29:0;2189:226:1;52583:607:0;53126:15;56244:1186;;;57182:12;:17;;;57172:28;57197:2;56244:1186;;17401:25:1;57222:14:0;17503:18:1;;;17496:43;;;;17555:18;;;17548:34;;;;57292:15:0;17598:18:1;;;17591:34;57329:16:0;17641:19:1;;;17634:35;57367:13:0;17685:19:1;;;17678:35;57402:10:0;17729:19:1;;;17722:44;-1:-1:-1;;17373:19:1;;56244:1186:0;;;;;;;;;;;;56217:1227;;;;;;56210:1234;;56114:1347;;53126:15;53118:4;:23;53117:62;;53175:4;53117:62;;;53155:16;;;;;;17034:25:1;;;17007:18;53155:16:0;;;;;;;;;;;;53145:27;;;;;;53117:62;53103:76;;52583:607;51245:1951;;51171:2025;;;:::o;58660:230::-;58753:25;;;;;:57;;-1:-1:-1;58782:23:0;;;;:28;58753:57;58749:135;;;58833:40;;;;;2365:42:1;58866:5:0;2353:55:1;58833:40:0;;;2335:74:1;2308:18;;58833:40:0;2189:226:1;58749:135:0;58660:230;:::o;59232:324::-;59404:7;59403:8;:43;;;-1:-1:-1;59415:26:0;;;;:31;59403:43;59399:151;;;59508:5;59527:10;59469:70;;;;;;;;;;;;:::i;59399:151::-;59232:324;;;:::o;57683:808::-;58343:7;58342:8;:37;;;-1:-1:-1;58354:25:0;;;;58342:37;:69;;;-1:-1:-1;58383:23:0;;;;:28;58342:69;58338:147;;;58434:40;;;;;2365:42:1;58467:5:0;2353:55:1;58434:40:0;;;2335:74:1;2308:18;;58434:40:0;2189:226:1;58338:147:0;57683:808;;:::o;53650:1723::-;53721:23;;53807:22;;;;53833:10;53807:36;:67;;;;-1:-1:-1;53854:4:0;53859:2;53854:8;;;53847:27;;;;;53807:67;53803:1564;;;-1:-1:-1;53931:21:0;;-1:-1:-1;53931:21:0;53650:1723;;;:::o;53803:1564::-;54003:22;;;;54029:10;54003:36;:67;;;;-1:-1:-1;54043:27:0;54055:2;54050:8;;;;;54043:27;;54003:67;53999:1368;;;-1:-1:-1;54127:21:0;;-1:-1:-1;54150:28:0;53650:1723;;;:::o;53999:1368::-;54226:10;54200:22;;;;:36;54196:1171;;-1:-1:-1;54293:21:0;;-1:-1:-1;54316:34:0;53650:1723;;;:::o;54196:1171::-;54372:22;;;;:36;:67;;;;-1:-1:-1;54419:4:0;54424:2;54419:8;;;54412:27;;;;;54372:67;54368:999;;;-1:-1:-1;54496:23:0;;-1:-1:-1;54521:27:0;53650:1723;;;:::o;54368:999::-;54570:22;;;;:36;:67;;;;-1:-1:-1;54610:27:0;54622:2;54617:8;;;;;54610:27;;54570:67;54566:801;;;-1:-1:-1;54694:23:0;;-1:-1:-1;54694:23:0;53650:1723;;;:::o;54566:801::-;54769:22;;;;54765:602;;-1:-1:-1;54862:23:0;;-1:-1:-1;54887:34:0;53650:1723;;;:::o;54765:602::-;54950:4;54955:2;54950:8;;;54943:27;;;;;54939:428;;-1:-1:-1;55027:18:0;;-1:-1:-1;55047:27:0;53650:1723;;;:::o;54939:428::-;55103:4;55108:2;55103:8;;;55096:27;;;;;55092:275;;-1:-1:-1;55180:18:0;;-1:-1:-1;55200:28:0;53650:1723;;;:::o;55092:275::-;-1:-1:-1;55301:18:0;;-1:-1:-1;55301:18:0;53650:1723;;;:::o;14:184:1:-;66:77;63:1;56:88;163:4;160:1;153:15;187:4;184:1;177:15;203:777;245:5;298:3;291:4;283:6;279:17;275:27;265:55;;316:1;313;306:12;265:55;352:6;339:20;378:18;415:2;411;408:10;405:36;;;421:18;;:::i;:::-;555:2;549:9;617:4;609:13;;460:66;605:22;;;629:2;601:31;597:40;585:53;;;653:18;;;673:22;;;650:46;647:72;;;699:18;;:::i;:::-;739:10;735:2;728:22;774:2;766:6;759:18;820:3;813:4;808:2;800:6;796:15;792:26;789:35;786:55;;;837:1;834;827:12;786:55;901:2;894:4;886:6;882:17;875:4;867:6;863:17;850:54;948:1;941:4;936:2;928:6;924:15;920:26;913:37;968:6;959:15;;;;;;203:777;;;;:::o;985:475::-;1038:5;1086:4;1074:9;1069:3;1065:19;1061:30;1058:50;;;1104:1;1101;1094:12;1058:50;1137:4;1131:11;1181:4;1173:6;1169:17;1252:6;1240:10;1237:22;1216:18;1204:10;1201:34;1198:62;1195:88;;;1263:18;;:::i;:::-;1299:4;1292:24;1364:23;;1349:39;;1449:2;1434:18;;;1421:32;1404:15;;;1397:57;;;;-1:-1:-1;1334:6:1;985:475;-1:-1:-1;985:475:1:o;1465:719::-;1591:6;1599;1607;1615;1668:3;1656:9;1647:7;1643:23;1639:33;1636:53;;;1685:1;1682;1675:12;1636:53;1721:9;1708:23;1698:33;;1782:2;1771:9;1767:18;1754:32;1805:18;1846:2;1838:6;1835:14;1832:34;;;1862:1;1859;1852:12;1832:34;1885:49;1926:7;1917:6;1906:9;1902:22;1885:49;:::i;:::-;1875:59;;1987:2;1976:9;1972:18;1959:32;1943:48;;2016:2;2006:8;2003:16;2000:36;;;2032:1;2029;2022:12;2000:36;;2055:51;2098:7;2087:8;2076:9;2072:24;2055:51;:::i;:::-;2045:61;;;2125:53;2170:7;2165:2;2154:9;2150:18;2125:53;:::i;:::-;2115:63;;1465:719;;;;;;;:::o;2420:388::-;2497:6;2505;2558:2;2546:9;2537:7;2533:23;2529:32;2526:52;;;2574:1;2571;2564:12;2526:52;2610:9;2597:23;2587:33;;2671:2;2660:9;2656:18;2643:32;2698:18;2690:6;2687:30;2684:50;;;2730:1;2727;2720:12;2684:50;2753:49;2794:7;2785:6;2774:9;2770:22;2753:49;:::i;:::-;2743:59;;;2420:388;;;;;:::o;2813:320::-;2881:6;2934:2;2922:9;2913:7;2909:23;2905:32;2902:52;;;2950:1;2947;2940:12;2902:52;2990:9;2977:23;3023:18;3015:6;3012:30;3009:50;;;3055:1;3052;3045:12;3009:50;3078:49;3119:7;3110:6;3099:9;3095:22;3078:49;:::i;3138:196::-;3206:20;;3266:42;3255:54;;3245:65;;3235:93;;3324:1;3321;3314:12;3235:93;3138:196;;;:::o;3339:462::-;3425:6;3433;3441;3494:2;3482:9;3473:7;3469:23;3465:32;3462:52;;;3510:1;3507;3500:12;3462:52;3546:9;3533:23;3523:33;;3575:38;3609:2;3598:9;3594:18;3575:38;:::i;:::-;3565:48;;3664:2;3653:9;3649:18;3636:32;3691:18;3683:6;3680:30;3677:50;;;3723:1;3720;3713:12;3677:50;3746:49;3787:7;3778:6;3767:9;3763:22;3746:49;:::i;:::-;3736:59;;;3339:462;;;;;:::o;3806:180::-;3865:6;3918:2;3906:9;3897:7;3893:23;3889:32;3886:52;;;3934:1;3931;3924:12;3886:52;-1:-1:-1;3957:23:1;;3806:180;-1:-1:-1;3806:180:1:o;3991:651::-;4108:6;4116;4124;4177:3;4165:9;4156:7;4152:23;4148:33;4145:53;;;4194:1;4191;4184:12;4145:53;4234:9;4221:23;4263:18;4304:2;4296:6;4293:14;4290:34;;;4320:1;4317;4310:12;4290:34;4343:49;4384:7;4375:6;4364:9;4360:22;4343:49;:::i;:::-;4333:59;;4445:2;4434:9;4430:18;4417:32;4401:48;;4474:2;4464:8;4461:16;4458:36;;;4490:1;4487;4480:12;4458:36;;4513:51;4556:7;4545:8;4534:9;4530:24;4513:51;:::i;:::-;4503:61;;;4583:53;4628:7;4623:2;4612:9;4608:18;4583:53;:::i;:::-;4573:63;;3991:651;;;;;:::o;4647:254::-;4715:6;4723;4776:2;4764:9;4755:7;4751:23;4747:32;4744:52;;;4792:1;4789;4782:12;4744:52;4828:9;4815:23;4805:33;;4857:38;4891:2;4880:9;4876:18;4857:38;:::i;:::-;4847:48;;4647:254;;;;;:::o;5091:::-;5159:6;5167;5220:2;5208:9;5199:7;5195:23;5191:32;5188:52;;;5236:1;5233;5226:12;5188:52;5259:29;5278:9;5259:29;:::i;:::-;5249:39;5335:2;5320:18;;;;5307:32;;-1:-1:-1;;;5091:254:1:o;5350:394::-;5427:6;5435;5488:2;5476:9;5467:7;5463:23;5459:32;5456:52;;;5504:1;5501;5494:12;5456:52;5527:29;5546:9;5527:29;:::i;:::-;5517:39;;5607:2;5596:9;5592:18;5579:32;5634:18;5626:6;5623:30;5620:50;;;5666:1;5663;5656:12;5749:248;5817:6;5825;5878:2;5866:9;5857:7;5853:23;5849:32;5846:52;;;5894:1;5891;5884:12;5846:52;-1:-1:-1;;5917:23:1;;;5987:2;5972:18;;;5959:32;;-1:-1:-1;5749:248:1:o;6002:726::-;6128:6;6136;6144;6152;6205:3;6193:9;6184:7;6180:23;6176:33;6173:53;;;6222:1;6219;6212:12;6173:53;6262:9;6249:23;6291:18;6332:2;6324:6;6321:14;6318:34;;;6348:1;6345;6338:12;6318:34;6371:49;6412:7;6403:6;6392:9;6388:22;6371:49;:::i;:::-;6361:59;;6473:2;6462:9;6458:18;6445:32;6429:48;;6502:2;6492:8;6489:16;6486:36;;;6518:1;6515;6508:12;6486:36;;6541:51;6584:7;6573:8;6562:9;6558:24;6541:51;:::i;:::-;6531:61;;;6611:53;6656:7;6651:2;6640:9;6636:18;6611:53;:::i;:::-;6601:63;;6683:39;6717:3;6706:9;6702:19;6683:39;:::i;6733:794::-;6868:6;6876;6884;6892;6900;6953:3;6941:9;6932:7;6928:23;6924:33;6921:53;;;6970:1;6967;6960:12;6921:53;7006:9;6993:23;6983:33;;7067:2;7056:9;7052:18;7039:32;7090:18;7131:2;7123:6;7120:14;7117:34;;;7147:1;7144;7137:12;7117:34;7170:49;7211:7;7202:6;7191:9;7187:22;7170:49;:::i;:::-;7160:59;;7272:2;7261:9;7257:18;7244:32;7228:48;;7301:2;7291:8;7288:16;7285:36;;;7317:1;7314;7307:12;7285:36;;7340:51;7383:7;7372:8;7361:9;7357:24;7340:51;:::i;:::-;7330:61;;;7410:53;7455:7;7450:2;7439:9;7435:18;7410:53;:::i;:::-;7400:63;;7482:39;7516:3;7505:9;7501:19;7482:39;:::i;:::-;7472:49;;6733:794;;;;;;;;:::o;7532:322::-;7609:6;7617;7625;7678:2;7666:9;7657:7;7653:23;7649:32;7646:52;;;7694:1;7691;7684:12;7646:52;7730:9;7717:23;7707:33;;7787:2;7776:9;7772:18;7759:32;7749:42;;7810:38;7844:2;7833:9;7829:18;7810:38;:::i;7859:250::-;7944:1;7954:113;7968:6;7965:1;7962:13;7954:113;;;8044:11;;;8038:18;8025:11;;;8018:39;7990:2;7983:10;7954:113;;;-1:-1:-1;;8101:1:1;8083:16;;8076:27;7859:250::o;8114:287::-;8243:3;8281:6;8275:13;8297:66;8356:6;8351:3;8344:4;8336:6;8332:17;8297:66;:::i;:::-;8379:16;;;;;8114:287;-1:-1:-1;;8114:287:1:o;8406:337::-;8474:18;8525:10;;;8513;;;8509:27;;8548:12;;;8545:192;;;8593:77;8590:1;8583:88;8694:4;8691:1;8684:15;8722:4;8719:1;8712:15;8545:192;;8406:337;;;;:::o;15538:573::-;15725:42;15717:6;15713:55;15702:9;15695:74;15805:2;15800;15789:9;15785:18;15778:30;15676:4;15837:6;15831:13;15880:6;15875:2;15864:9;15860:18;15853:34;15896:79;15968:6;15963:2;15952:9;15948:18;15943:2;15935:6;15931:15;15896:79;:::i;:::-;16027:2;16015:15;16032:66;16011:88;15996:104;;;;16102:2;15992:113;;15538:573;-1:-1:-1;;;15538:573:1:o;16326:184::-;16378:77;16375:1;16368:88;16475:4;16472:1;16465:15;16499:4;16496:1;16489:15
Swarm Source
none
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.