Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6558919 | 31 hrs ago | Contract Creation | 0 S |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Deployer
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 800 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: Unlicense pragma solidity 0.8.27; import "./Create3.sol"; import "./SoladyOwnable.sol"; import {ECDSA} from "solady/utils/ECDSA.sol"; contract Deployer is SoladyOwnable { event ContractDeployed(address indexed contractAddress); error InvalidBytecodeSignature(); using ECDSA for bytes32; constructor(address _owner) SoladyOwnable(_owner) {} function deploy(bytes32 _salt, bytes calldata _creationCode, bytes calldata signature) external returns (address deployedContract) { bytes32 hash = keccak256(abi.encode(_creationCode, _salt, block.chainid)); if (!_verifySignature(hash, signature)) revert InvalidBytecodeSignature(); deployedContract = Create3.create3(_salt, _creationCode); emit ContractDeployed(deployedContract); } function deploy(bytes32 _salt, bytes calldata _creationCode) onlyOwner external returns (address deployedContract) { deployedContract = Create3.create3(_salt, _creationCode); emit ContractDeployed(deployedContract); } function addressOf(bytes32 _salt) external view returns (address) { return Create3.addressOf(_salt); } function _verifySignature(bytes32 hash, bytes calldata signature) internal view returns (bool) { if (hash.recoverCalldata(signature) == owner()) return true; if (hash.toEthSignedMessageHash().recoverCalldata(signature) == owner()) return true; return false; } }
//SPDX-License-Identifier: Unlicense pragma solidity 0.8.27; /** @title A library for deploying contracts EIP-3171 style. @author Agustin Aguilar <[email protected]> */ library Create3 { error ErrorCreatingProxy(); error ErrorCreatingContract(); error TargetAlreadyExists(); /** @notice The bytecode for a contract that proxies the creation of another contract @dev If this code is deployed using CREATE2 it can be used to decouple `creationCode` from the child contract address 0x67363d3d37363d34f03d5260086018f3: 0x00 0x67 0x67XXXXXXXXXXXXXXXX PUSH8 bytecode 0x363d3d37363d34f0 0x01 0x3d 0x3d RETURNDATASIZE 0 0x363d3d37363d34f0 0x02 0x52 0x52 MSTORE 0x03 0x60 0x6008 PUSH1 08 8 0x04 0x60 0x6018 PUSH1 18 24 8 0x05 0xf3 0xf3 RETURN 0x363d3d37363d34f0: 0x00 0x36 0x36 CALLDATASIZE cds 0x01 0x3d 0x3d RETURNDATASIZE 0 cds 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds 0x03 0x37 0x37 CALLDATACOPY 0x04 0x36 0x36 CALLDATASIZE cds 0x05 0x3d 0x3d RETURNDATASIZE 0 cds 0x06 0x34 0x34 CALLVALUE val 0 cds 0x07 0xf0 0xf0 CREATE addr */ bytes internal constant PROXY_CHILD_BYTECODE = hex"67_36_3d_3d_37_36_3d_34_f0_3d_52_60_08_60_18_f3"; // KECCAK256_PROXY_CHILD_BYTECODE = keccak256(PROXY_CHILD_BYTECODE); bytes32 internal constant KECCAK256_PROXY_CHILD_BYTECODE = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f; /** @notice Returns the size of the code on a given address @param _addr Address that may or may not contain code @return size of the code on the given `_addr` */ function codeSize(address _addr) internal view returns (uint256 size) { assembly { size := extcodesize(_addr) } } /** @notice Creates a new contract with given `_creationCode` and `_salt` @param _salt Salt of the contract creation, resulting address will be derivated from this value only @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address @return addr of the deployed contract, reverts on error */ function create3( bytes32 _salt, bytes memory _creationCode ) internal returns (address addr) { return create3(_salt, _creationCode, 0); } /** @notice Creates a new contract with given `_creationCode` and `_salt` @param _salt Salt of the contract creation, resulting address will be derivated from this value only @param _creationCode Creation code (constructor) of the contract to be deployed, this value doesn't affect the resulting address @param _value In WEI of ETH to be forwarded to child contract @return addr of the deployed contract, reverts on error */ function create3( bytes32 _salt, bytes memory _creationCode, uint256 _value ) internal returns (address addr) { // Creation code bytes memory creationCode = PROXY_CHILD_BYTECODE; // Get target final address addr = addressOf(_salt); if (codeSize(addr) != 0) revert TargetAlreadyExists(); // Create CREATE2 proxy address proxy; assembly { proxy := create2( 0, add(creationCode, 32), mload(creationCode), _salt ) } if (proxy == address(0)) revert ErrorCreatingProxy(); // Call proxy with final init code (bool success, ) = proxy.call{value: _value}(_creationCode); if (!success || codeSize(addr) == 0) revert ErrorCreatingContract(); } function addressOfProxy(bytes32 _salt) internal view returns (address) { return address( uint160( uint256( keccak256( abi.encodePacked( hex"ff", address(this), _salt, KECCAK256_PROXY_CHILD_BYTECODE ) ) ) ) ); } /** @notice Computes the resulting address of a contract deployed using address(this) and the given `_salt` @param _salt Salt of the contract creation, resulting address will be derivated from this value only @return addr of the deployed contract, reverts on error @dev The address creation formula is: keccak256(rlp([keccak256(0xff ++ address(this) ++ _salt ++ keccak256(childBytecode))[12:], 0x01])) */ function addressOf(bytes32 _salt) internal view returns (address) { address proxy = addressOfProxy(_salt); return address( uint160( uint256( keccak256(abi.encodePacked(hex"d6_94", proxy, hex"01")) ) ) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.27; import { Ownable } from "solady/auth/Ownable.sol"; contract SoladyOwnable is Ownable { constructor(address _owner) Ownable() { assembly { if iszero(shl(96, _owner)) { mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. revert(0x1c, 0x04) } } _initializeOwner(_owner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Gas optimized ECDSA wrapper. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) /// /// @dev Note: /// - The recovery functions use the ecrecover precompile (0x1). /// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure. /// This is for more safety by default. /// Use the `tryRecover` variants if you need to get the zero address back /// upon recovery failure instead. /// - As of Solady version 0.0.134, all `bytes signature` variants accept both /// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. /// See: https://eips.ethereum.org/EIPS/eip-2098 /// This is for calldata efficiency on smart accounts prevalent on L2s. /// /// WARNING! Do NOT directly use signatures as unique identifiers: /// - The recovery operations do NOT check if a signature is non-malleable. /// - Use a nonce in the digest to prevent replay attacks on the same contract. /// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. /// EIP-712 also enables readable signing of typed data for better user safety. /// - If you need a unique hash from a signature, please use the `canonicalHash` functions. library ECDSA { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The order of the secp256k1 elliptic curve. uint256 internal constant N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141; /// @dev `N/2 + 1`. Used for checking the malleability of the signature. uint256 private constant _HALF_N_PLUS_1 = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The signature is invalid. error InvalidSignature(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* RECOVERY OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function recover(bytes32 hash, bytes memory signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { for { let m := mload(0x40) } 1 { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } { switch mload(signature) case 64 { let vs := mload(add(signature, 0x40)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x60, shr(1, shl(1, vs))) // `s`. } case 65 { mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x60, mload(add(signature, 0x40))) // `s`. } default { continue } mstore(0x00, hash) mstore(0x40, mload(add(signature, 0x20))) // `r`. result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if returndatasize() { break } } } } /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function recoverCalldata(bytes32 hash, bytes calldata signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { for { let m := mload(0x40) } 1 { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } { switch signature.length case 64 { let vs := calldataload(add(signature.offset, 0x20)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, calldataload(signature.offset)) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. } case 65 { mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. } default { continue } mstore(0x00, hash) result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if returndatasize() { break } } } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the EIP-2098 short form signature defined by `r` and `vs`. function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, r) mstore(0x60, shr(1, shl(1, vs))) // `s`. result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the signature defined by `v`, `r`, `s`. function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, and(v, 0xff)) mstore(0x40, r) mstore(0x60, s) result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20)) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* TRY-RECOVER OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // WARNING! // These functions will NOT revert upon recovery failure. // Instead, they will return the zero address upon recovery failure. // It is critical that the returned address is NEVER compared against // a zero address (e.g. an uninitialized address variable). /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function tryRecover(bytes32 hash, bytes memory signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { for { let m := mload(0x40) } 1 {} { switch mload(signature) case 64 { let vs := mload(add(signature, 0x40)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x60, shr(1, shl(1, vs))) // `s`. } case 65 { mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x60, mload(add(signature, 0x40))) // `s`. } default { break } mstore(0x00, hash) mstore(0x40, mload(add(signature, 0x20))) // `r`. pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. break } } } /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function tryRecoverCalldata(bytes32 hash, bytes calldata signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { for { let m := mload(0x40) } 1 {} { switch signature.length case 64 { let vs := calldataload(add(signature.offset, 0x20)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, calldataload(signature.offset)) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. } case 65 { mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. } default { break } mstore(0x00, hash) pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. break } } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the EIP-2098 short form signature defined by `r` and `vs`. function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, r) mstore(0x60, shr(1, shl(1, vs))) // `s`. pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the signature defined by `v`, `r`, `s`. function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, and(v, 0xff)) mstore(0x40, r) mstore(0x60, s) pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20)) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HASHING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an Ethereum Signed Message, created from a `hash`. /// This produces a hash corresponding to the one signed with the /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign) /// JSON-RPC method as part of EIP-191. function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, hash) // Store into scratch space for keccak256. mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. } } /// @dev Returns an Ethereum Signed Message, created from `s`. /// This produces a hash corresponding to the one signed with the /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign) /// JSON-RPC method as part of EIP-191. /// Note: Supports lengths of `s` up to 999999 bytes. function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { let sLength := mload(s) let o := 0x20 mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded. mstore(0x00, 0x00) // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`. for { let temp := sLength } 1 {} { o := sub(o, 1) mstore8(o, add(48, mod(temp, 10))) temp := div(temp, 10) if iszero(temp) { break } } let n := sub(0x3a, o) // Header length: `26 + 32 - o`. // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes. returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20)) mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header. result := keccak256(add(s, sub(0x20, n)), add(n, sLength)) mstore(s, sLength) // Restore the length. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CANONICAL HASH FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // The following functions returns the hash of the signature in it's canonicalized format, // which is the 65-byte `abi.encodePacked(r, s, uint8(v))`, where `v` is either 27 or 28. // If `s` is greater than `N / 2` then it will be converted to `N - s` // and the `v` value will be flipped. // If the signature has an invalid length, or if `v` is invalid, // a uniquely corrupt hash will be returned. // These functions are useful for "poor-mans-VRF". /// @dev Returns the canonical hash of `signature`. function canonicalHash(bytes memory signature) internal pure returns (bytes32 result) { // @solidity memory-safe-assembly assembly { let l := mload(signature) for {} 1 {} { mstore(0x00, mload(add(signature, 0x20))) // `r`. let s := mload(add(signature, 0x40)) let v := mload(add(signature, 0x41)) if eq(l, 64) { v := add(shr(255, s), 27) s := shr(1, shl(1, s)) } if iszero(lt(s, _HALF_N_PLUS_1)) { v := xor(v, 7) s := sub(N, s) } mstore(0x21, v) mstore(0x20, s) result := keccak256(0x00, 0x41) mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. break } // If the length is neither 64 nor 65, return a uniquely corrupted hash. if iszero(lt(sub(l, 64), 2)) { // `bytes4(keccak256("InvalidSignatureLength"))`. result := xor(keccak256(add(signature, 0x20), l), 0xd62f1ab2) } } } /// @dev Returns the canonical hash of `signature`. function canonicalHashCalldata(bytes calldata signature) internal pure returns (bytes32 result) { // @solidity memory-safe-assembly assembly { for {} 1 {} { mstore(0x00, calldataload(signature.offset)) // `r`. let s := calldataload(add(signature.offset, 0x20)) let v := calldataload(add(signature.offset, 0x21)) if eq(signature.length, 64) { v := add(shr(255, s), 27) s := shr(1, shl(1, s)) } if iszero(lt(s, _HALF_N_PLUS_1)) { v := xor(v, 7) s := sub(N, s) } mstore(0x21, v) mstore(0x20, s) result := keccak256(0x00, 0x41) mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. break } // If the length is neither 64 nor 65, return a uniquely corrupted hash. if iszero(lt(sub(signature.length, 64), 2)) { calldatacopy(mload(0x40), signature.offset, signature.length) // `bytes4(keccak256("InvalidSignatureLength"))`. result := xor(keccak256(mload(0x40), signature.length), 0xd62f1ab2) } } } /// @dev Returns the canonical hash of `signature`. function canonicalHash(bytes32 r, bytes32 vs) internal pure returns (bytes32 result) { // @solidity memory-safe-assembly assembly { mstore(0x00, r) // `r`. let v := add(shr(255, vs), 27) let s := shr(1, shl(1, vs)) mstore(0x21, v) mstore(0x20, s) result := keccak256(0x00, 0x41) mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Returns the canonical hash of `signature`. function canonicalHash(uint8 v, bytes32 r, bytes32 s) internal pure returns (bytes32 result) { // @solidity memory-safe-assembly assembly { mstore(0x00, r) // `r`. if iszero(lt(s, _HALF_N_PLUS_1)) { v := xor(v, 7) s := sub(N, s) } mstore(0x21, v) mstore(0x20, s) result := keccak256(0x00, 0x41) mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EMPTY CALLDATA HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an empty calldata bytes. function emptySignature() internal pure returns (bytes calldata signature) { /// @solidity memory-safe-assembly assembly { signature.length := 0 } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Simple single owner authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// /// @dev Note: /// This implementation does NOT auto-initialize the owner to `msg.sender`. /// You MUST call the `_initializeOwner` in the constructor / initializer. /// /// While the ownable portion follows /// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, /// the nomenclature for the 2-step ownership handover may be unique to this codebase. abstract contract Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The caller is not authorized to call the function. error Unauthorized(); /// @dev The `newOwner` cannot be the zero address. error NewOwnerIsZeroAddress(); /// @dev The `pendingOwner` does not have a valid handover request. error NoHandoverRequest(); /// @dev Cannot double-initialize. error AlreadyInitialized(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership is transferred from `oldOwner` to `newOwner`. /// This event is intentionally kept the same as OpenZeppelin's Ownable to be /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), /// despite it not being as lightweight as a single argument event. event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// @dev An ownership handover to `pendingOwner` has been requested. event OwnershipHandoverRequested(address indexed pendingOwner); /// @dev The ownership handover to `pendingOwner` has been canceled. event OwnershipHandoverCanceled(address indexed pendingOwner); /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The owner slot is given by: /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`. /// It is intentionally chosen to be a high value /// to avoid collision with lower slots. /// The choice of manual storage layout is to enable compatibility /// with both regular and upgradeable contracts. bytes32 internal constant _OWNER_SLOT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927; /// The ownership handover slot of `newOwner` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) /// let handoverSlot := keccak256(0x00, 0x20) /// ``` /// It stores the expiry timestamp of the two-step ownership handover. uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Override to return true to make `_initializeOwner` prevent double-initialization. function _guardInitializeOwner() internal pure virtual returns (bool guard) {} /// @dev Initializes the owner directly without authorization guard. /// This function must be called upon initialization, /// regardless of whether the contract is upgradeable or not. /// This is to enable generalization to both regular and upgradeable contracts, /// and to save gas in case the initial owner is not the caller. /// For performance reasons, this function will not check if there /// is an existing owner. function _initializeOwner(address newOwner) internal virtual { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT if sload(ownerSlot) { mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`. revert(0x1c, 0x04) } // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } else { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(_OWNER_SLOT, newOwner) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } } /// @dev Sets the owner directly without authorization guard. function _setOwner(address newOwner) internal virtual { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) } } else { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, newOwner) } } } /// @dev Throws if the sender is not the owner. function _checkOwner() internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner, revert. if iszero(eq(caller(), sload(_OWNER_SLOT))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. /// Override to return a different value if needed. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ownershipHandoverValidFor() internal view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to transfer the ownership to `newOwner`. function transferOwnership(address newOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { if iszero(shl(96, newOwner)) { mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. revert(0x1c, 0x04) } } _setOwner(newOwner); } /// @dev Allows the owner to renounce their ownership. function renounceOwnership() public payable virtual onlyOwner { _setOwner(address(0)); } /// @dev Request a two-step ownership handover to the caller. /// The request will automatically expire in 48 hours (172800 seconds) by default. function requestOwnershipHandover() public payable virtual { unchecked { uint256 expires = block.timestamp + _ownershipHandoverValidFor(); /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to `expires`. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), expires) // Emit the {OwnershipHandoverRequested} event. log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) } } } /// @dev Cancels the two-step ownership handover to the caller, if any. function cancelOwnershipHandover() public payable virtual { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), 0) // Emit the {OwnershipHandoverCanceled} event. log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) } } /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. /// Reverts if there is no existing ownership handover requested by `pendingOwner`. function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) let handoverSlot := keccak256(0x0c, 0x20) // If the handover does not exist, or has expired. if gt(timestamp(), sload(handoverSlot)) { mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`. revert(0x1c, 0x04) } // Set the handover slot to 0. sstore(handoverSlot, 0) } _setOwner(pendingOwner); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of the contract. function owner() public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { result := sload(_OWNER_SLOT) } } /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. function ownershipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Compute the handover slot. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) // Load the handover slot. result := sload(keccak256(0x0c, 0x20)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } }
{ "remappings": [ "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", "@prb/test/=node_modules/@prb/test/", "@nexus/=node_modules/nexus/", "forge-std/=lib/forge-std/src/", "account-abstraction/=node_modules/account-abstraction/contracts/", "@ERC4337/account-abstraction/=node_modules/account-abstraction/", "@modulekit/=node_modules/modulekit/src/", "sentinellist/=node_modules/sentinellist/src/", "solady/=node_modules/solady/src/", "@uniswap/v3-periphery/contracts/=node_modules/@uniswap/v3-periphery/contracts/", "@uniswap/v3-core/contracts/=node_modules/@uniswap/v3-core/contracts/", "@uniswap/swap-router-contracts/contracts/=node_modules/@uniswap/swap-router-contracts/contracts/", "solady/src/=node_modules/solady/src/", "excessively-safe-call/=node_modules/excessively-safe-call/src/", "modulekit/=node_modules/@rhinestone/modulekit/src/", "module-bases/=node_modules/module-bases/src/", "erc7579/=node_modules/erc7579/src/", "kernel/=node_modules/@zerodev/kernel/src/", "@safe-global/=node_modules/@safe-global/", "solarray/=node_modules/solarray/src/", "erc7739Validator/=node_modules/erc7739-validator-base/src/", "@biconomy-devx/=node_modules/@biconomy-devx/", "@erc7579/=node_modules/@erc7579/", "@gnosis.pm/=node_modules/@gnosis.pm/", "@prb/math/=node_modules/erc7739-validator-base/node_modules/@prb/math/src/", "@rhinestone/=node_modules/@rhinestone/", "@zerodev/=node_modules/@zerodev/", "ExcessivelySafeCall/=node_modules/erc7739-validator-base/node_modules/excessively-safe-call/src/", "account-abstraction-v0.6/=node_modules/account-abstraction-v0.6/", "accountabstraction/=node_modules/accountabstraction/", "base64-sol/=node_modules/base64-sol/", "ds-test/=node_modules/ds-test/", "enumerableset4337/=node_modules/erc7739-validator-base/node_modules/@erc7579/enumerablemap4337/src/", "erc4337-validation/=node_modules/erc7739-validator-base/node_modules/@rhinestone/erc4337-validation/src/", "erc7739-validator-base/=node_modules/erc7739-validator-base/", "hardhat-deploy/=node_modules/hardhat-deploy/", "hardhat/=node_modules/hardhat/", "nexus/=node_modules/nexus/", "registry/=node_modules/modulekit/node_modules/@rhinestone/registry/src/", "safe7579/=node_modules/erc7739-validator-base/node_modules/@rhinestone/safe7579/src/" ], "optimizer": { "enabled": true, "runs": 800 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ErrorCreatingContract","type":"error"},{"inputs":[],"name":"ErrorCreatingProxy","type":"error"},{"inputs":[],"name":"InvalidBytecodeSignature","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"TargetAlreadyExists","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"}],"name":"addressOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_salt","type":"bytes32"},{"internalType":"bytes","name":"_creationCode","type":"bytes"}],"name":"deploy","outputs":[{"internalType":"address","name":"deployedContract","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
34605f57610984388190036080601f8201601f19168101906001600160401b03821190821017606357602092829160405260803912605f576080516001600160a01b0381168103605f576050906077565b6040516108be90816100c68239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b8060601b1560b8576001600160a01b0316638b78c6d8198190555f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a3565b637448fbae5f526004601cfdfe60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b6104de565b6104ae565b61046a565b61032e565b6102ff565b6102d5565b61028c565b610248565b6101ff565b346101cd5760603660031901126101cd5760043560243567ffffffffffffffff81116101cd576100e89036906004016101d1565b9160443567ffffffffffffffff81116101cd5761015461010f6101589236906004016101d1565b90606060a05286610100528686610120375f61012088015261014960a0601f19601f8a01168760c0524660e0526080810160805201610519565b60805160a0206105b5565b1590565b6101be5761016e610174926101ba94369161057f565b90610850565b60405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f840112156101cd5782359167ffffffffffffffff83116101cd57602083818601950101116101cd57565b5f3660031901126101cd5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f3660031901126101cd5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f3660031901126101cd5761029f61062b565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b346101cd575f3660031901126101cd576020638b78c6d819546001600160a01b0360405191168152f35b346101cd5760203660031901126101cd57602061031d600435610685565b6001600160a01b0360405191168152f35b346101cd5760403660031901126101cd5760043560243567ffffffffffffffff81116101cd576103656103749136906004016101d1565b61036d61062b565b369161057f565b61037c6107e6565b9161038681610685565b92833b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af16103bb610821565b50158015610421575b610412576101ba9060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b6353de54b960e01b5f5260045ffd5b50803b156103c4565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b60209060031901126101cd576004356001600160a01b03811681036101cd5790565b61047336610448565b61047b61062b565b63389a75e1600c52805f526020600c2090815442116104a1575f61049f9255610647565b005b636f5e88185f526004601cfd5b6104b736610448565b6104bf61062b565b8060601b156104d15761049f90610647565b637448fbae5f526004601cfd5b346101cd576104ec36610448565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b601f80199101166080016080811067ffffffffffffffff82111761053c57604052565b610505565b90601f8019910116810190811067ffffffffffffffff82111761053c57604052565b67ffffffffffffffff811161053c57601f01601f191660200190565b92919261058b82610563565b916105996040519384610541565b8294818452818301116101cd578281602093845f960137010152565b6001600160a01b03926105c981848461074b565b638b78c6d81954851694168414610622576001600160a01b0392610613926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042061074b565b161461061d575f90565b600190565b50505050600190565b638b78c6d81954330361063a57565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b61073c6001600160a01b0361074892604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6055820152605581526106e6607582610541565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b60368201526017815261072d603782610541565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146107a65760411461077457505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6107a4575050610767565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c016020523560405216606052610783565b604051906107f5604083610541565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d1561084b573d9061083282610563565b916108406040519384610541565b82523d5f602084013e565b606090565b919061085a6107e6565b9261086481610685565b93843b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af1610899610821565b501580156108a8575b61041257565b50813b156108a256fea164736f6c634300081b000a000000000000000000000000336a8f5251f3b0723d04fbdd25858fca02bb22e3
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c806319cdeff1146100b457806325692962146100af57806354d1f13d146100aa578063715018a6146100a55780638da5cb5b146100a0578063bb34534c1461009b578063cdcb760a14610096578063f04e283e14610091578063f2fde38b1461008c5763fee81cf414610087575f80fd5b6104de565b6104ae565b61046a565b61032e565b6102ff565b6102d5565b61028c565b610248565b6101ff565b346101cd5760603660031901126101cd5760043560243567ffffffffffffffff81116101cd576100e89036906004016101d1565b9160443567ffffffffffffffff81116101cd5761015461010f6101589236906004016101d1565b90606060a05286610100528686610120375f61012088015261014960a0601f19601f8a01168760c0524660e0526080810160805201610519565b60805160a0206105b5565b1590565b6101be5761016e610174926101ba94369161057f565b90610850565b60405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b0390f35b6306f691ef60e51b5f5260045ffd5b5f80fd5b9181601f840112156101cd5782359167ffffffffffffffff83116101cd57602083818601950101116101cd57565b5f3660031901126101cd5763389a75e1600c52335f526202a30042016020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a2005b5f3660031901126101cd5763389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2005b5f3660031901126101cd5761029f61062b565b5f638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a35f638b78c6d81955005b346101cd575f3660031901126101cd576020638b78c6d819546001600160a01b0360405191168152f35b346101cd5760203660031901126101cd57602061031d600435610685565b6001600160a01b0360405191168152f35b346101cd5760403660031901126101cd5760043560243567ffffffffffffffff81116101cd576103656103749136906004016101d1565b61036d61062b565b369161057f565b61037c6107e6565b9161038681610685565b92833b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af16103bb610821565b50158015610421575b610412576101ba9060405191816001600160a01b038493167f8ffcdc15a283d706d38281f500270d8b5a656918f555de0913d7455e3e6bc1bf5f80a26001600160a01b031682526020820190565b6353de54b960e01b5f5260045ffd5b50803b156103c4565b63bbd2fe8760e01b5f5260045ffd5b63cd43efa160e01b5f5260045ffd5b60209060031901126101cd576004356001600160a01b03811681036101cd5790565b61047336610448565b61047b61062b565b63389a75e1600c52805f526020600c2090815442116104a1575f61049f9255610647565b005b636f5e88185f526004601cfd5b6104b736610448565b6104bf61062b565b8060601b156104d15761049f90610647565b637448fbae5f526004601cfd5b346101cd576104ec36610448565b63389a75e1600c525f52602080600c2054604051908152f35b634e487b7160e01b5f52604160045260245ffd5b601f80199101166080016080811067ffffffffffffffff82111761053c57604052565b610505565b90601f8019910116810190811067ffffffffffffffff82111761053c57604052565b67ffffffffffffffff811161053c57601f01601f191660200190565b92919261058b82610563565b916105996040519384610541565b8294818452818301116101cd578281602093845f960137010152565b6001600160a01b03926105c981848461074b565b638b78c6d81954851694168414610622576001600160a01b0392610613926020527b19457468657265756d205369676e6564204d6573736167653a0a33325f52603c60042061074b565b161461061d575f90565b600190565b50505050600190565b638b78c6d81954330361063a57565b6382b429005f526004601cfd5b6001600160a01b031680638b78c6d819547f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3638b78c6d81955565b61073c6001600160a01b0361074892604051602081019160ff60f81b83523060601b602183015260358201527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6055820152605581526106e6607582610541565b5190206040516135a560f21b602082019081529290911660601b6bffffffffffffffffffffffff19166022820152600160f81b60368201526017815261072d603782610541565b5190206001600160a01b031690565b6001600160a01b031690565b90565b9092919260405193806040146107a65760411461077457505050505b638baa579f5f526004601cfd5b806040809201355f1a60205281375b5f526020600160805f825afa51915f6060526040523d6107a4575050610767565b565b508060207f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92013590601b8260ff1c016020523560405216606052610783565b604051906107f5604083610541565b601082527f67363d3d37363d34f03d5260086018f3000000000000000000000000000000006020830152565b3d1561084b573d9061083282610563565b916108406040519384610541565b82523d5f602084013e565b606090565b919061085a6107e6565b9261086481610685565b93843b610439576020815191015ff56001600160a01b0381161561042a57815f92918360208194519301915af1610899610821565b501580156108a8575b61041257565b50813b156108a256fea164736f6c634300081b000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000336a8f5251f3b0723d04fbdd25858fca02bb22e3
-----Decoded View---------------
Arg [0] : _owner (address): 0x336A8f5251F3b0723d04FBDD25858fca02BB22E3
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000336a8f5251f3b0723d04fbdd25858fca02bb22e3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.