Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
L1Resolver
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {EVMFetcher} from "linea-state-verifier/contracts/EVMFetcher.sol"; import {EVMFetchTarget} from "linea-state-verifier/contracts/EVMFetchTarget.sol"; import {IEVMVerifier} from "linea-state-verifier/contracts/IEVMVerifier.sol"; import "@ensdomains/ens-contracts/contracts/registry/ENS.sol"; import {INameWrapper} from "@ensdomains/ens-contracts/contracts/wrapper/INameWrapper.sol"; import {BytesUtils} from "@ensdomains/ens-contracts/contracts/dnssec-oracle/BytesUtils.sol"; import {IAddrResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IAddrResolver.sol"; import {IAddressResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IAddressResolver.sol"; import {ITextResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol"; import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol"; import "@ensdomains/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol"; import {ITargetResolver} from "./ITargetResolver.sol"; import {IMetadataResolver} from "./IMetadataResolver.sol"; import {IAddrSetter} from "./IAddrSetter.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; contract L1Resolver is EVMFetchTarget, ITargetResolver, IMetadataResolver, IExtendedResolver, IAddrSetter, ERC165 { using EVMFetcher for EVMFetcher.EVMFetchRequest; using BytesUtils for bytes; IEVMVerifier public immutable verifier; ENS public immutable ens; INameWrapper public immutable nameWrapper; uint256 public immutable l2ChainId; mapping(bytes32 => address) targets; uint256 constant COIN_TYPE_ETH = 60; uint256 constant RECORD_VERSIONS_SLOT = 0; uint256 constant VERSIONABLE_ABIS_SLOT = 1; uint256 constant VERSIONABLE_ADDRESSES_SLOT = 2; uint256 constant VERSIONABLE_HASHES_SLOT = 3; uint256 constant VERSIONABLE_TEXTS_SLOT = 10; // To check how old is the value/proof returned and is in the acceptable range uint256 constant ACCEPTED_L2_BLOCK_RANGE_LENGTH = 86400; string public graphqlUrl; event TargetSet(bytes name, address target); function isAuthorised(bytes32 node) internal view returns (bool) { // TODO: Add support for // trustedETHController // trustedReverseRegistrar // isApprovedForAll // isApprovedFor address owner = ens.owner(node); if (owner == address(nameWrapper)) { owner = nameWrapper.ownerOf(uint256(node)); } return owner == msg.sender; } /** * @dev EIP-5559 - Error to raise when mutations are being deferred to an L2. * @param chainId Chain ID to perform the deferred mutation to. * @param contractAddress Contract Address at which the deferred mutation should transact with. */ error StorageHandledByL2(uint256 chainId, address contractAddress); /** * @param _verifier The chain verifier address * @param _ens The ENS registry address * @param _nameWrapper The ENS name wrapper address * @param _graphqlUrl The offchain/l2 graphql endpoint url * @param _l2ChainId The chainId at which the resolver resolves data from */ constructor( IEVMVerifier _verifier, ENS _ens, INameWrapper _nameWrapper, string memory _graphqlUrl, uint256 _l2ChainId ) { require( address(_nameWrapper) != address(0), "Name Wrapper address must be set" ); require( address(_verifier) != address(0), "Verifier address must be set" ); require(address(_ens) != address(0), "Registry address must be set"); verifier = _verifier; ens = _ens; nameWrapper = _nameWrapper; graphqlUrl = _graphqlUrl; l2ChainId = _l2ChainId; } /** * @dev inherits from EVMFetchTarget */ function getAcceptedL2BlockRangeLength() public pure override returns (uint256) { return ACCEPTED_L2_BLOCK_RANGE_LENGTH; } /** * Set target address to verify against * @param name The encoded name to query. * @param target The L2 resolver address to verify against. */ function setTarget(bytes calldata name, address target) external { (bytes32 node, ) = getTarget(name); require( isAuthorised(node), "Not authorized to set target for this node" ); targets[node] = target; emit TargetSet(name, target); emit MetadataChanged(name, graphqlUrl); } /** * @dev Returns the L2 target address that can answer queries for `name`. * @param name DNS encoded ENS name to query * @return node The node of the name * @return target The L2 resolver address to verify against. */ function getTarget( bytes memory name ) public view returns (bytes32 node, address target) { return _getTarget(name, 0); } function _getTarget( bytes memory name, uint256 offset ) private view returns (bytes32 node, address target) { uint256 len = name.readUint8(offset); node = bytes32(0); if (len > 0) { bytes32 label = name.keccak(offset + 1, len); (node, target) = _getTarget(name, offset + len + 1); node = keccak256(abi.encodePacked(node, label)); if (targets[node] != address(0)) { return (node, targets[node]); } } else { return (bytes32(0), address(0)); } return (node, target); } /** * @dev Resolve and verify a record stored in l2 target address. It supports subname by fetching target recursively to the nearest parent. * @param name DNS encoded ENS name to query * @param data The actual calldata * @return result result of the call */ function resolve( bytes calldata name, bytes calldata data ) external view returns (bytes memory result) { require(data.length >= 4, "param data too short"); (, address target) = _getTarget(name, 0); bytes4 selector = bytes4(data); if (selector == IAddrResolver.addr.selector) { bytes32 node = abi.decode(data[4:], (bytes32)); return _addr(node, target); } if (selector == IAddressResolver.addr.selector) { (bytes32 node, uint256 cointype) = abi.decode( data[4:], (bytes32, uint256) ); return _addr(node, cointype, target); } if (selector == ITextResolver.text.selector) { (bytes32 node, string memory key) = abi.decode( data[4:], (bytes32, string) ); return bytes(_text(node, key, target)); } if (selector == IContentHashResolver.contenthash.selector) { bytes32 node = abi.decode(data[4:], (bytes32)); return _contenthash(node, target); } // None selector has been found it reverts revert("invalid selector"); } /** * @dev Resolve and throws an EIP 3559 compliant error * @param name DNS encoded ENS name to query * @param _addr The actual calldata * @return result result of the call */ function setAddr( bytes calldata name, address _addr ) external view returns (bytes memory result) { (, address target) = _getTarget(name, 0); _writeDeferral(target); } function _addr( bytes32 node, address target ) private view returns (bytes memory) { EVMFetcher .newFetchRequest(verifier, target) .getStatic(RECORD_VERSIONS_SLOT) .element(node) .getDynamic(VERSIONABLE_ADDRESSES_SLOT) .ref(0) .element(node) .element(COIN_TYPE_ETH) .fetch(this.addrCallback.selector, ""); // recordVersions } function addrCallback( bytes[] memory values, bytes memory ) external pure returns (bytes memory) { return abi.encode(address(bytes20(values[1]))); } function _addr( bytes32 node, uint256 coinType, address target ) private view returns (bytes memory) { EVMFetcher .newFetchRequest(verifier, target) .getStatic(RECORD_VERSIONS_SLOT) .element(node) .getDynamic(VERSIONABLE_ADDRESSES_SLOT) .ref(0) .element(node) .element(coinType) .fetch(this.addrCoinTypeCallback.selector, ""); } function addrCoinTypeCallback( bytes[] memory values, bytes memory ) external pure returns (bytes memory) { return abi.encode(values[1]); } function _text( bytes32 node, string memory key, address target ) private view returns (bytes memory) { EVMFetcher .newFetchRequest(verifier, target) .getStatic(RECORD_VERSIONS_SLOT) .element(node) .getDynamic(VERSIONABLE_TEXTS_SLOT) .ref(0) .element(node) .element(key) .fetch(this.textCallback.selector, ""); } function textCallback( bytes[] memory values, bytes memory ) external pure returns (bytes memory) { return abi.encode(string(values[1])); } function _contenthash( bytes32 node, address target ) private view returns (bytes memory) { EVMFetcher .newFetchRequest(verifier, target) .getStatic(RECORD_VERSIONS_SLOT) .element(node) .getDynamic(VERSIONABLE_HASHES_SLOT) .ref(0) .element(node) .fetch(this.contenthashCallback.selector, ""); } function contenthashCallback( bytes[] memory values, bytes memory ) external pure returns (bytes memory) { return abi.encode(values[1]); } /** * @notice Get metadata about the L1 Resolver * @dev This function provides metadata about the L1 Resolver, including its name, coin type, GraphQL URL, storage type, and encoded information. * @param name The domain name in format (dnsEncoded) * @return graphqlUrl The GraphQL URL used by the resolver */ function metadata( bytes calldata name ) external view returns (string memory) { return (graphqlUrl); } function supportsInterface( bytes4 interfaceId ) public view override returns (bool) { return interfaceId == type(IExtendedResolver).interfaceId || interfaceId == type(ITargetResolver).interfaceId || interfaceId == type(IMetadataResolver).interfaceId || interfaceId == type(IAddrSetter).interfaceId || super.supportsInterface(interfaceId); } function _writeDeferral(address target) internal view { revert StorageHandledByL2(l2ChainId, target); } }
pragma solidity ^0.8.4; library BytesUtils { error OffsetOutOfBoundsError(uint256 offset, uint256 length); /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak( bytes memory self, uint256 offset, uint256 len ) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. * @param self The first bytes to compare. * @param other The second bytes to compare. * @return The result of the comparison. */ function compare( bytes memory self, bytes memory other ) internal pure returns (int256) { return compare(self, 0, self.length, other, 0, other.length); } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first bytes to compare. * @param offset The offset of self. * @param len The length of self. * @param other The second bytes to compare. * @param otheroffset The offset of the other string. * @param otherlen The length of the other string. * @return The result of the comparison. */ function compare( bytes memory self, uint256 offset, uint256 len, bytes memory other, uint256 otheroffset, uint256 otherlen ) internal pure returns (int256) { if (offset + len > self.length) { revert OffsetOutOfBoundsError(offset + len, self.length); } if (otheroffset + otherlen > other.length) { revert OffsetOutOfBoundsError(otheroffset + otherlen, other.length); } uint256 shortest = len; if (otherlen < len) shortest = otherlen; uint256 selfptr; uint256 otherptr; assembly { selfptr := add(self, add(offset, 32)) otherptr := add(other, add(otheroffset, 32)) } for (uint256 idx = 0; idx < shortest; idx += 32) { uint256 a; uint256 b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint256 mask; if (shortest - idx >= 32) { mask = type(uint256).max; } else { mask = ~(2 ** (8 * (idx + 32 - shortest)) - 1); } int256 diff = int256(a & mask) - int256(b & mask); if (diff != 0) return diff; } selfptr += 32; otherptr += 32; } return int256(len) - int256(otherlen); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @param len The number of bytes to compare * @return True if the byte ranges are equal, false otherwise. */ function equals( bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset, uint256 len ) internal pure returns (bool) { return keccak(self, offset, len) == keccak(other, otherOffset, len); } /* * @dev Returns true if the two byte ranges are equal with offsets. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @return True if the byte ranges are equal, false otherwise. */ function equals( bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset ) internal pure returns (bool) { return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); } /* * @dev Compares a range of 'self' to all of 'other' and returns True iff * they are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals( bytes memory self, uint256 offset, bytes memory other ) internal pure returns (bool) { return self.length == offset + other.length && equals(self, offset, other, 0, other.length); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals( bytes memory self, bytes memory other ) internal pure returns (bool) { return self.length == other.length && equals(self, 0, other, 0, self.length); } /* * @dev Returns the 8-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 8 bits of the string, interpreted as an integer. */ function readUint8( bytes memory self, uint256 idx ) internal pure returns (uint8 ret) { return uint8(self[idx]); } /* * @dev Returns the 16-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 16 bits of the string, interpreted as an integer. */ function readUint16( bytes memory self, uint256 idx ) internal pure returns (uint16 ret) { require(idx + 2 <= self.length); assembly { ret := and(mload(add(add(self, 2), idx)), 0xFFFF) } } /* * @dev Returns the 32-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bits of the string, interpreted as an integer. */ function readUint32( bytes memory self, uint256 idx ) internal pure returns (uint32 ret) { require(idx + 4 <= self.length); assembly { ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes32( bytes memory self, uint256 idx ) internal pure returns (bytes32 ret) { require(idx + 32 <= self.length); assembly { ret := mload(add(add(self, 32), idx)) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes20( bytes memory self, uint256 idx ) internal pure returns (bytes20 ret) { require(idx + 20 <= self.length); assembly { ret := and( mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ) } } /* * @dev Returns the n byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes. * @param len The number of bytes. * @return The specified 32 bytes of the string. */ function readBytesN( bytes memory self, uint256 idx, uint256 len ) internal pure returns (bytes32 ret) { require(len <= 32); require(idx + len <= self.length); assembly { let mask := not(sub(exp(256, sub(32, len)), 1)) ret := and(mload(add(add(self, 32), idx)), mask) } } function memcpy(uint256 dest, uint256 src, uint256 len) private pure { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint256 mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } } /* * @dev Copies a substring into a new byte string. * @param self The byte string to copy from. * @param offset The offset to start copying at. * @param len The number of bytes to copy. */ function substring( bytes memory self, uint256 offset, uint256 len ) internal pure returns (bytes memory) { require(offset + len <= self.length); bytes memory ret = new bytes(len); uint256 dest; uint256 src; assembly { dest := add(ret, 32) src := add(add(self, 32), offset) } memcpy(dest, src, len); return ret; } // Maps characters from 0x30 to 0x7A to their base32 values. // 0xFF represents invalid characters in that range. bytes constant base32HexTable = hex"00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; /** * @dev Decodes unpadded base32 data of up to one word in length. * @param self The data to decode. * @param off Offset into the string to start at. * @param len Number of characters to decode. * @return The decoded data, left aligned. */ function base32HexDecodeWord( bytes memory self, uint256 off, uint256 len ) internal pure returns (bytes32) { require(len <= 52); uint256 ret = 0; uint8 decoded; for (uint256 i = 0; i < len; i++) { bytes1 char = self[off + i]; require(char >= 0x30 && char <= 0x7A); decoded = uint8(base32HexTable[uint256(uint8(char)) - 0x30]); require(decoded <= 0x20); if (i == len - 1) { break; } ret = (ret << 5) | decoded; } uint256 bitlen = len * 5; if (len % 8 == 0) { // Multiple of 8 characters, no padding ret = (ret << 5) | decoded; } else if (len % 8 == 2) { // Two extra characters - 1 byte ret = (ret << 3) | (decoded >> 2); bitlen -= 2; } else if (len % 8 == 4) { // Four extra characters - 2 bytes ret = (ret << 1) | (decoded >> 4); bitlen -= 4; } else if (len % 8 == 5) { // Five extra characters - 3 bytes ret = (ret << 4) | (decoded >> 1); bitlen -= 1; } else if (len % 8 == 7) { // Seven extra characters - 4 bytes ret = (ret << 2) | (decoded >> 3); bitlen -= 3; } else { revert(); } return bytes32(ret << (256 - bitlen)); } /** * @dev Finds the first occurrence of the byte `needle` in `self`. * @param self The string to search * @param off The offset to start searching at * @param len The number of bytes to search * @param needle The byte to search for * @return The offset of `needle` in `self`, or 2**256-1 if it was not found. */ function find( bytes memory self, uint256 off, uint256 len, bytes1 needle ) internal pure returns (uint256) { for (uint256 idx = off; idx < off + len; idx++) { if (self[idx] == needle) { return idx; } } return type(uint256).max; } }
import "../registry/ENS.sol"; import "./IBaseRegistrar.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; interface IBaseRegistrar is IERC721 { event ControllerAdded(address indexed controller); event ControllerRemoved(address indexed controller); event NameMigrated( uint256 indexed id, address indexed owner, uint256 expires ); event NameRegistered( uint256 indexed id, address indexed owner, uint256 expires ); event NameRenewed(uint256 indexed id, uint256 expires); // Authorises a controller, who can register and renew domains. function addController(address controller) external; // Revoke controller permission for an address. function removeController(address controller) external; // Set the resolver for the TLD this registrar manages. function setResolver(address resolver) external; // Returns the expiration timestamp of the specified label hash. function nameExpires(uint256 id) external view returns (uint256); // Returns true if the specified name is available for registration. function available(uint256 id) external view returns (bool); /** * @dev Register a name. */ function register( uint256 id, address owner, uint256 duration ) external returns (uint256); function renew(uint256 id, uint256 duration) external returns (uint256); /** * @dev Reclaim ownership of a name in ENS, if you own it in the registrar. */ function reclaim(uint256 id, address owner) external; }
pragma solidity >=0.8.4; interface ENS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function setRecord( bytes32 node, address owner, address resolver, uint64 ttl ) external; function setSubnodeRecord( bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl ) external; function setSubnodeOwner( bytes32 node, bytes32 label, address owner ) external returns (bytes32); function setResolver(bytes32 node, address resolver) external; function setOwner(bytes32 node, address owner) external; function setTTL(bytes32 node, uint64 ttl) external; function setApprovalForAll(address operator, bool approved) external; function owner(bytes32 node) external view returns (address); function resolver(bytes32 node) external view returns (address); function ttl(bytes32 node) external view returns (uint64); function recordExists(bytes32 node) external view returns (bool); function isApprovedForAll( address owner, address operator ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the new (multicoin) addr function. */ interface IAddressResolver { event AddressChanged( bytes32 indexed node, uint256 coinType, bytes newAddress ); function addr( bytes32 node, uint256 coinType ) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; /** * Interface for the legacy (ETH-only) addr function. */ interface IAddrResolver { event AddrChanged(bytes32 indexed node, address a); /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) external view returns (address payable); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IContentHashResolver { event ContenthashChanged(bytes32 indexed node, bytes hash); /** * Returns the contenthash associated with an ENS node. * @param node The ENS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IExtendedResolver { function resolve( bytes memory name, bytes memory data ) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface ITextResolver { event TextChanged( bytes32 indexed node, string indexed indexedKey, string key, string value ); /** * Returns the text data associated with an ENS node and key. * @param node The ENS node to query. * @param key The text data key to query. * @return The associated text data. */ function text( bytes32 node, string calldata key ) external view returns (string memory); }
//SPDX-License-Identifier: MIT pragma solidity ~0.8.17; interface IMetadataService { function uri(uint256) external view returns (string memory); }
//SPDX-License-Identifier: MIT pragma solidity ~0.8.17; import "../registry/ENS.sol"; import "../ethregistrar/IBaseRegistrar.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "./IMetadataService.sol"; import "./INameWrapperUpgrade.sol"; uint32 constant CANNOT_UNWRAP = 1; uint32 constant CANNOT_BURN_FUSES = 2; uint32 constant CANNOT_TRANSFER = 4; uint32 constant CANNOT_SET_RESOLVER = 8; uint32 constant CANNOT_SET_TTL = 16; uint32 constant CANNOT_CREATE_SUBDOMAIN = 32; uint32 constant CANNOT_APPROVE = 64; //uint16 reserved for parent controlled fuses from bit 17 to bit 32 uint32 constant PARENT_CANNOT_CONTROL = 1 << 16; uint32 constant IS_DOT_ETH = 1 << 17; uint32 constant CAN_EXTEND_EXPIRY = 1 << 18; uint32 constant CAN_DO_EVERYTHING = 0; uint32 constant PARENT_CONTROLLED_FUSES = 0xFFFF0000; // all fuses apart from IS_DOT_ETH uint32 constant USER_SETTABLE_FUSES = 0xFFFDFFFF; interface INameWrapper is IERC1155 { event NameWrapped( bytes32 indexed node, bytes name, address owner, uint32 fuses, uint64 expiry ); event NameUnwrapped(bytes32 indexed node, address owner); event FusesSet(bytes32 indexed node, uint32 fuses); event ExpiryExtended(bytes32 indexed node, uint64 expiry); function ens() external view returns (ENS); function registrar() external view returns (IBaseRegistrar); function metadataService() external view returns (IMetadataService); function names(bytes32) external view returns (bytes memory); function name() external view returns (string memory); function upgradeContract() external view returns (INameWrapperUpgrade); function supportsInterface(bytes4 interfaceID) external view returns (bool); function wrap( bytes calldata name, address wrappedOwner, address resolver ) external; function wrapETH2LD( string calldata label, address wrappedOwner, uint16 ownerControlledFuses, address resolver ) external returns (uint64 expires); function registerAndWrapETH2LD( string calldata label, address wrappedOwner, uint256 duration, address resolver, uint16 ownerControlledFuses ) external returns (uint256 registrarExpiry); function renew( uint256 labelHash, uint256 duration ) external returns (uint256 expires); function unwrap(bytes32 node, bytes32 label, address owner) external; function unwrapETH2LD( bytes32 label, address newRegistrant, address newController ) external; function upgrade(bytes calldata name, bytes calldata extraData) external; function setFuses( bytes32 node, uint16 ownerControlledFuses ) external returns (uint32 newFuses); function setChildFuses( bytes32 parentNode, bytes32 labelhash, uint32 fuses, uint64 expiry ) external; function setSubnodeRecord( bytes32 node, string calldata label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry ) external returns (bytes32); function setRecord( bytes32 node, address owner, address resolver, uint64 ttl ) external; function setSubnodeOwner( bytes32 node, string calldata label, address newOwner, uint32 fuses, uint64 expiry ) external returns (bytes32); function extendExpiry( bytes32 node, bytes32 labelhash, uint64 expiry ) external returns (uint64); function canModifyName( bytes32 node, address addr ) external view returns (bool); function setResolver(bytes32 node, address resolver) external; function setTTL(bytes32 node, uint64 ttl) external; function ownerOf(uint256 id) external view returns (address owner); function approve(address to, uint256 tokenId) external; function getApproved(uint256 tokenId) external view returns (address); function getData( uint256 id ) external view returns (address, uint32, uint64); function setMetadataService(IMetadataService _metadataService) external; function uri(uint256 tokenId) external view returns (string memory); function setUpgradeContract(INameWrapperUpgrade _upgradeAddress) external; function allFusesBurned( bytes32 node, uint32 fuseMask ) external view returns (bool); function isWrapped(bytes32) external view returns (bool); function isWrapped(bytes32, bytes32) external view returns (bool); }
//SPDX-License-Identifier: MIT pragma solidity ~0.8.17; interface INameWrapperUpgrade { function wrapFromUpgrade( bytes calldata name, address wrappedOwner, uint32 fuses, uint64 expiry, address approved, bytes calldata extraData ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; interface IAddrSetter { function setAddr( bytes calldata name, address _addr ) external view returns (bytes memory result); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; interface IMetadataResolver { /* * @notice Get metadata about the CCIP Resolver ENSIP 16 https://docs.ens.domains/ens-improvement-proposals/ensip-16-offchain-metadata * @dev This function provides metadata about the CCIP Resolver, including its name, coin type, GraphQL URL, storage type, and encoded information. * @param name The domain name in format (dnsEncoded) * @return graphqlUrl The GraphQL URL used by the resolver * */ function metadata( bytes calldata name ) external view returns (string memory graphqlUrl); event MetadataChanged(bytes name, string graphqlUrl); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; interface ITargetResolver { function getTarget( bytes memory name ) external view returns (bytes32 node, address target); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {IEVMVerifier} from "./IEVMVerifier.sol"; import {EVMFetchTarget} from "./EVMFetchTarget.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; interface IEVMGateway { function getStorageSlots( address addr, bytes32[] memory commands, bytes[] memory constants ) external pure returns (bytes memory witness); } uint8 constant FLAG_DYNAMIC = 0x01; uint8 constant OP_CONSTANT = 0x00; uint8 constant OP_BACKREF = 0x20; uint8 constant OP_END = 0xff; /** * @dev A library to facilitate requesting storage data proofs from contracts, possibly on a different chain. * See l1-verifier/test/TestL1.sol for example usage. */ library EVMFetcher { uint256 constant MAX_COMMANDS = 32; uint256 constant MAX_CONSTANTS = 32; // Must not be greater than 32 using Address for address; error TooManyCommands(uint256 max); error CommandTooLong(); error InvalidReference(uint256 value, uint256 max); error OffchainLookup( address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData ); struct EVMFetchRequest { IEVMVerifier verifier; address target; bytes32[] commands; uint256 operationIdx; bytes[] constants; } /** * @dev Creates a request to fetch the value of multiple storage slots from a contract via CCIP-Read, possibly from * another chain. * Supports dynamic length values and slot numbers derived from other retrieved values. * @param verifier An instance of a verifier contract that can provide and verify the storage slot information. * @param target The address of the contract to fetch storage proofs for. */ function newFetchRequest( IEVMVerifier verifier, address target ) internal pure returns (EVMFetchRequest memory) { bytes32[] memory commands = new bytes32[](MAX_COMMANDS); bytes[] memory constants = new bytes[](MAX_CONSTANTS); assembly { mstore(commands, 0) // Set current array length to 0 mstore(constants, 0) } return EVMFetchRequest(verifier, target, commands, 0, constants); } /** * @dev Starts describing a new fetch request. * Paths specify a series of hashing operations to derive the final slot ID. * See https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html for details on how Solidity * lays out storage variables. * @param request The request object being operated on. * @param baseSlot The base slot ID that forms the root of the path. */ function getStatic( EVMFetchRequest memory request, uint256 baseSlot ) internal pure returns (EVMFetchRequest memory) { bytes32[] memory commands = request.commands; uint256 commandIdx = commands.length; if (commandIdx > 0 && request.operationIdx < 32) { // Terminate previous command _addOperation(request, OP_END); } assembly { mstore(commands, add(commandIdx, 1)) // Increment command array length } if (request.commands.length > MAX_COMMANDS) { revert TooManyCommands(MAX_COMMANDS); } request.operationIdx = 0; _addOperation(request, 0); _addOperation(request, _addConstant(request, abi.encode(baseSlot))); return request; } /** * @dev Starts describing a new fetch request. * Paths specify a series of hashing operations to derive the final slot ID. * See https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_storage.html for details on how Solidity * lays out storage variables. * @param request The request object being operated on. * @param baseSlot The base slot ID that forms the root of the path. */ function getDynamic( EVMFetchRequest memory request, uint256 baseSlot ) internal pure returns (EVMFetchRequest memory) { bytes32[] memory commands = request.commands; uint256 commandIdx = commands.length; if (commandIdx > 0 && request.operationIdx < 32) { // Terminate previous command _addOperation(request, OP_END); } assembly { mstore(commands, add(commandIdx, 1)) // Increment command array length } if (request.commands.length > MAX_COMMANDS) { revert TooManyCommands(MAX_COMMANDS); } request.operationIdx = 0; _addOperation(request, FLAG_DYNAMIC); _addOperation(request, _addConstant(request, abi.encode(baseSlot))); return request; } /** * @dev Adds a `uint256` element to the current path. * @param request The request object being operated on. * @param el The element to add. */ function element( EVMFetchRequest memory request, uint256 el ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } _addOperation(request, _addConstant(request, abi.encode(el))); return request; } /** * @dev Adds a `bytes32` element to the current path. * @param request The request object being operated on. * @param el The element to add. */ function element( EVMFetchRequest memory request, bytes32 el ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } _addOperation(request, _addConstant(request, abi.encode(el))); return request; } /** * @dev Adds an `address` element to the current path. * @param request The request object being operated on. * @param el The element to add. */ function element( EVMFetchRequest memory request, address el ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } _addOperation(request, _addConstant(request, abi.encode(el))); return request; } /** * @dev Adds a `bytes` element to the current path. * @param request The request object being operated on. * @param el The element to add. */ function element( EVMFetchRequest memory request, bytes memory el ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } _addOperation(request, _addConstant(request, el)); return request; } /** * @dev Adds a `string` element to the current path. * @param request The request object being operated on. * @param el The element to add. */ function element( EVMFetchRequest memory request, string memory el ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } _addOperation(request, _addConstant(request, bytes(el))); return request; } /** * @dev Adds a reference to a previous fetch to the current path. * @param request The request object being operated on. * @param idx The index of the previous fetch request, starting at 0. */ function ref( EVMFetchRequest memory request, uint8 idx ) internal pure returns (EVMFetchRequest memory) { if (request.operationIdx >= 32) { revert CommandTooLong(); } if (idx > request.commands.length || idx > 31) { revert InvalidReference(idx, request.commands.length); } _addOperation(request, OP_BACKREF | idx); return request; } /** * @dev Initiates the fetch request. * Calling this function terminates execution; clients that implement CCIP-Read will make a callback to * `callback` with the results of the operation. * @param callbackId A callback function selector on this contract that will be invoked via CCIP-Read with the result of the lookup. * The function must have a signature matching `(bytes[] memory values, bytes callbackData)` with a return type matching the call in which * this function was invoked. Its return data will be returned as the return value of the entire CCIP-read operation. * @param callbackData Extra data to supply to the callback. */ function fetch( EVMFetchRequest memory request, bytes4 callbackId, bytes memory callbackData ) internal view { if (request.commands.length > 0 && request.operationIdx < 32) { // Terminate last command _addOperation(request, OP_END); } revert OffchainLookup( address(this), request.verifier.gatewayURLs(), abi.encodeCall( IEVMGateway.getStorageSlots, (request.target, request.commands, request.constants) ), EVMFetchTarget.getStorageSlotsCallback.selector, abi.encode( request.verifier, request.target, request.commands, request.constants, callbackId, callbackData ) ); } function _addConstant( EVMFetchRequest memory request, bytes memory value ) private pure returns (uint8 idx) { bytes[] memory constants = request.constants; idx = uint8(constants.length); assembly { mstore(constants, add(idx, 1)) // Increment constant array length } constants[idx] = value; } function _addOperation( EVMFetchRequest memory request, uint8 op ) private pure { uint256 commandIdx = request.commands.length - 1; request.commands[commandIdx] = request.commands[commandIdx] | (bytes32(bytes1(op)) >> (8 * request.operationIdx++)); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import {IEVMVerifier} from "./IEVMVerifier.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; /** * @dev Callback implementation for users of `EVMFetcher`. If you use `EVMFetcher`, your contract must * inherit from this contract in order to handle callbacks correctly. */ abstract contract EVMFetchTarget { using Address for address; error ResponseLengthMismatch(uint256 actual, uint256 expected); /** * @dev Internal callback function invoked by CCIP-Read in response to a `getStorageSlots` request. */ function getStorageSlotsCallback( bytes calldata response, bytes calldata extradata ) external returns (bytes memory) { bytes memory proof = abi.decode(response, (bytes)); ( IEVMVerifier verifier, address addr, bytes32[] memory commands, bytes[] memory constants, bytes4 callback, bytes memory callbackData ) = abi.decode( extradata, (IEVMVerifier, address, bytes32[], bytes[], bytes4, bytes) ); bytes[] memory values = verifier.getStorageValues( addr, commands, constants, proof, getAcceptedL2BlockRangeLength() ); if (values.length != commands.length) { revert ResponseLengthMismatch(values.length, commands.length); } bytes memory ret = address(this).functionCall( abi.encodeWithSelector(callback, values, callbackData) ); assembly { return(add(ret, 32), mload(ret)) } } /** * @dev The child contract has to return an accepted L2 block range used by the verifier * to verify that the block number verified is in the accepted block range. */ function getAcceptedL2BlockRangeLength() public view virtual returns (uint256); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.25; interface IEVMVerifier { function gatewayURLs() external view returns (string[] memory); function getStorageValues( address target, bytes32[] memory commands, bytes[] memory constants, bytes memory proof, uint256 acceptedL2BlockRangeLength ) external view returns (bytes[] memory values); }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IEVMVerifier","name":"_verifier","type":"address"},{"internalType":"contract ENS","name":"_ens","type":"address"},{"internalType":"contract INameWrapper","name":"_nameWrapper","type":"address"},{"internalType":"string","name":"_graphqlUrl","type":"string"},{"internalType":"uint256","name":"_l2ChainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CommandTooLong","type":"error"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"max","type":"uint256"}],"name":"InvalidReference","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"ResponseLengthMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"}],"name":"StorageHandledByL2","type":"error"},{"inputs":[{"internalType":"uint256","name":"max","type":"uint256"}],"name":"TooManyCommands","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"string","name":"graphqlUrl","type":"string"}],"name":"MetadataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"address","name":"target","type":"address"}],"name":"TargetSet","type":"event"},{"inputs":[{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"addrCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"addrCoinTypeCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"contenthashCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"ens","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAcceptedL2BlockRangeLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extradata","type":"bytes"}],"name":"getStorageSlotsCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"}],"name":"getTarget","outputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"target","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"graphqlUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"}],"name":"metadata","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nameWrapper","outputs":[{"internalType":"contract INameWrapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"address","name":"_addr","type":"address"}],"name":"setAddr","outputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"address","name":"target","type":"address"}],"name":"setTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"values","type":"bytes[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"textCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract IEVMVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523461038857612666803803908161001b8161038d565b91823960a08183810103126103885780516001600160a01b039182821682036103885760208101518381168103610388576040820151908482168203610388576060830151936001600160401b03851161038857601f938781018587830101121561038857808601516001600160401b03811161028e57601f19966100a6828801891660200161038d565b99828b5283016020838386010101116103885760005b82811061037257505060009089016020015260800151958381161561032e57808216156102e9578216156102a45760805260a05260c0528351906001600160401b03821161028e5760019283548481811c91168015610284575b602082101461026e57828111610226575b5060209183116001146101c75750819293946000926101bc575b5050600019600383901b1c191690821b1790555b60e0526040516122b390816103b3823960805181818161037101528181611463015281816116520152818161179f01526118a3015260a05181818161054c0152610a5e015260c0518181816109a10152610a93015260e051818181610c6e0152610cc00152f35b015190503880610141565b8216908360005260206000209160005b81811061021057509583859697106101f7575b505050811b019055610155565b015160001960f88460031b161c191690553880806101ea565b87830151845592850192602092830192016101d7565b8460005260206000208380860160051c82019260208710610265575b0160051c019085905b828110610259575050610127565b6000815501859061024b565b92508192610242565b634e487b7160e01b600052602260045260246000fd5b90607f1690610116565b634e487b7160e01b600052604160045260246000fd5b60405162461bcd60e51b815260206004820152601c60248201527f52656769737472792061646472657373206d75737420626520736574000000006044820152606490fd5b60405162461bcd60e51b815260206004820152601c60248201527f56657269666965722061646472657373206d75737420626520736574000000006044820152606490fd5b606460405162461bcd60e51b815260206004820152602060248201527f4e616d6520577261707065722061646472657373206d757374206265207365746044820152fd5b602082850182018101518c8301820152016100bc565b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761028e5760405256fe6080604052600436101561001257600080fd5b60003560e01c806301ffc9a71461011d57806315f64386146101185780632b7ac3f31461011357806338bf92e6146100d75780633f15457f1461010e5780634062b43f146101095780635bdaa916146101045780636d74e86e146100ff5780638a596ebe146100fa5780639061b923146100f5578063a8e5fbc0146100f0578063d358df77146100eb578063d6ae3cd5146100e6578063de9abe5e146100d7578063f00eebf4146100e1578063f470901a146100dc5763fcd2e381146100d757600080fd5b6104d2565b610cf8565b610c91565b610c56565b610a19565b61098b565b61086d565b610828565b61080a565b61070c565b61066a565b610536565b61035b565b61030a565b61013c565b35906001600160e01b03198216820361013757565b600080fd5b346101375760203660031901126101375760043563ffffffff60e01b81168091036101375761019f90639061b92360e01b81149081156101d6575b81156101c5575b81156101b4575b81156101a3575b5060405190151581529081906020820190565b0390f35b6301ffc9a760e01b1490503861018c565b633c03bafd60e21b81149150610185565b63452cb75f60e11b8114915061017e565b630afb21c360e11b81149150610177565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761021857604052565b6101e7565b602081019081106001600160401b0382111761021857604052565b61042081019081106001600160401b0382111761021857604052565b90601f801991011681019081106001600160401b0382111761021857604052565b6001600160401b03811161021857601f01601f191660200190565b92919261029c82610275565b916102aa6040519384610254565b829481845281830111610137578281602093846000960137010152565b9080601f83011215610137578160206102e293359101610290565b90565b906020828203126101375781356001600160401b038111610137576102e292016102c7565b34610137576020366003190112610137576004356001600160401b03811161013757610346600061034160409336906004016102c7565b611309565b82519182526001600160a01b03166020820152f35b34610137576000366003190112610137576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6001600160401b0381116102185760051b60200190565b81601f82011215610137578035916020916103d1846103a0565b936103df6040519586610254565b808552838086019160051b8301019280841161013757848301915b84831061040a5750505050505090565b82356001600160401b03811161013757869161042b848480948901016102c7565b8152019201916103fa565b906040600319830112610137576001600160401b036004358181116101375783610462916004016103b7565b92602435918211610137576102e2916004016102c7565b60005b83811061048c5750506000910152565b818101518382015260200161047c565b906020916104b581518092818552858086019101610479565b601f01601f1916010190565b9060206102e292818152019061049c565b34610137576104e036610436565b508051600110156105315761050f61051d604061019f930151604051928391602080840152604083019061049c565b03601f198101835282610254565b60405191829160208352602083019061049c565b610d80565b34610137576000366003190112610137576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b90600182811c921680156105ab575b602083101461059557565b634e487b7160e01b600052602260045260246000fd5b91607f169161058a565b906000916001906001546105c88161057b565b808352926020916001811690811561064557506001146105e9575b50505050565b9293945060016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6926000935b8585106106325750505060209250010190388080806105e3565b8054858501840152938201938101610618565b92505050602093945060ff929192191683830152151560051b010190388080806105e3565b346101375760003660031901126101375761019f60405161051d8161068e816105b5565b0382610254565b9181601f84011215610137578235916001600160401b038311610137576020838186019501011161013757565b6040600319820112610137576001600160401b039160043583811161013757826106ee91600401610695565b939093926024359182116101375761070891600401610695565b9091565b346101375761076b600061073161073a610725366106c2565b949183919301906102e5565b92810190610daa565b95839592979460018060a09b949b1b039283926040519a8b978896879563628e501560e11b87521660048601610ff3565b0392165afa928315610805576000936107e0575b5082519051908181036107ba576107b2846107ac8761050f8760405194859360208501526024840161104f565b306113ce565b602081519101f35b604051632918942560e01b815260048101919091526024810191909152604490fd5b0390fd5b6107fe9193503d806000833e6107f68183610254565b810190610eb8565b913861077f565b611043565b34610137576000366003190112610137576020604051620151808152f35b34610137576020366003190112610137576004356001600160401b03811161013757610858903690600401610695565b505061019f60405161051d8161068e816105b5565b3461013757610341600061089c610883366106c2565b94929095916108956004871015611074565b3691610290565b9290506001600160e01b03196108b283836110b7565b16631d9dabef60e11b8114610977576378e5bf0360e11b811461095a57631674750f60e21b811461093d5763bc1c58d160e01b146109225760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b21039b2b632b1ba37b960811b6044820152606490fd5b8161093892610930926110e3565b810190611100565b611895565b50816109549261094c926110e3565b810190611125565b90611790565b508161097192610969926110e3565b81019061110f565b90611638565b508161098692610930926110e3565b61144d565b34610137576000366003190112610137576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b6001600160a01b0381160361013757565b604060031982011261013757600435906001600160401b03821161013757610a0b91600401610695565b90916024356102e2816109d0565b3461013757610a27366109e1565b91610a386000610341368585610290565b506040516302571be360e01b8152600481018290526001600160a01b03602080836024817f000000000000000000000000000000000000000000000000000000000000000086165afa92831561080557600093610c35575b507f00000000000000000000000000000000000000000000000000000000000000008216908383168214610b71575b505094610b4c81610b2d7f88781081cc340609705af0f96bf3ba64ea267873444e91725bd072f2af0f44d895610b1d610b5a967f3c68652dbd57659176ef0092991d5753aac3039c3134b7a3eb5689acfaccf62d9b33911614611164565b6000526000602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b6040519182918686846111e4565b0390a1610b6c6040519283928361120d565b0390a1005b6040516331a9108f60e11b8152600481018690529790935091908390889060249082905afa801561080557610b2d7f88781081cc340609705af0f96bf3ba64ea267873444e91725bd072f2af0f44d895610b1d610b4c9486947f3c68652dbd57659176ef0092991d5753aac3039c3134b7a3eb5689acfaccf62d9c610b5a99600092610c08575b50509750959a5050955050610abf565b610c279250803d10610c2e575b610c1f8183610254565b81019061195c565b3880610bf8565b503d610c15565b819350610c4f9083923d8611610c2e57610c1f8183610254565b9290610a90565b346101375760003660031901126101375760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b34610137576044610cb16000610341610ca9366109e1565b503691610290565b60405163e0a0507160e01b81527f000000000000000000000000000000000000000000000000000000000000000060048201526001600160a01b0390911660248201529050fd5b3461013757610d0636610436565b508051600110156105315761050f610d5f604061019f93015160208151910151906bffffffffffffffffffffffff19918281169160148110610d6b575b50506040805160609290921c6020830152909384925090820190565b604051918291826104c1565b8391925060140360031b1b1616803880610d43565b634e487b7160e01b600052603260045260246000fd5b80518210156105315760209160051b010190565b91909160c081840312610137578035610dc2816109d0565b92602080830135610dd2816109d0565b936001600160401b039160408501358381116101375785019084601f8301121561013757813591610e02836103a0565b92610e106040519485610254565b808452828085019160051b83010191878311610137578301905b828210610e7257505050509360608101358381116101375784610e4e9183016103b7565b93610e5b60808301610122565b9360a0830135908111610137576102e292016102c7565b81358152908301908301610e2a565b90929192610e8e81610275565b91610e9c6040519384610254565b829482845282820111610137576020610eb6930190610479565b565b9060209081838203126101375782516001600160401b039384821161013757019080601f83011215610137578151610eef816103a0565b94604090610f006040519788610254565b828752858088019360051b8601019484861161013757868101935b868510610f2d57505050505050505090565b845183811161013757820186603f82011215610137578891610f5788838886809601519101610e81565b815201940193610f1b565b90815180825260208080930193019160005b828110610f82575050505090565b835185529381019392810192600101610f74565b90808251908181526020809101926020808460051b8301019501936000915b848310610fc55750505050505090565b9091929394958480610fe3600193601f198682030187528a5161049c565b9801930193019194939290610fb5565b9493611030620151809461102260809561103e9560018060a01b03168a5260a060208b015260a08a0190610f62565b9088820360408a0152610f96565b90868203606088015261049c565b930152565b6040513d6000823e3d90fd5b90916110666102e293604084526040840190610f96565b91602081840391015261049c565b1561107b57565b60405162461bcd60e51b81526020600482015260146024820152731c185c985b4819185d18481d1bdbc81cda1bdc9d60621b6044820152606490fd5b6001600160e01b031990358181169392600481106110d457505050565b60040360031b82901b16169150565b909291928360041161013757831161013757600401916003190190565b90816020910312610137573590565b9190826040910312610137576020823592013590565b9190604083820312610137578235926020810135906001600160401b03821161013757019080601f83011215610137578160206102e293359101610290565b1561116b57565b60405162461bcd60e51b815260206004820152602a60248201527f4e6f7420617574686f72697a656420746f207365742074617267657420666f726044820152692074686973206e6f646560b01b6064820152608490fd5b908060209392818452848401376000828201840152601f01601f1916010190565b916020916111fd919594956040855260408501916111c3565b6001600160a01b03909416910152565b9190611221916040845260408401916111c3565b8181036020928301526001805460009392909161123d8361057b565b80835292600181169081156112b6575060011461125c575b5050505090565b9293509060016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf692846000945b8386106112a25750505050010138808080611255565b80548587018301529401938590820161128c565b60ff191685840152505090151560051b0101905038808080611255565b634e487b7160e01b600052601160045260246000fd5b90600182018092116112f757565b6112d3565b919082018092116112f757565b9190918051831015610531576020838201015160f81c80156113c2579061134e611349836113436113549561133d896112e9565b86611971565b966112fc565b6112e9565b90611309565b60408051602081019384529081019490945292611374816060810161050f565b51902060008181526020819052604090206001600160a01b03906113a0905b546001600160a01b031690565b166113a9579190565b91506102e2611393836000526000602052604060002090565b50509050600090600090565b906102e291600080604051936113e3856101fd565b601e85527f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000602086015260208151910182855af13d15611445573d9161142883610275565b926114366040519485610254565b83523d6000602085013e612059565b606091612059565b61148c6114966114918361148c61148761149b977f00000000000000000000000000000000000000000000000000000000000000006119c8565b611a64565b611adb565b611b0f565b611b86565b6114a361198b565b5060608101906020908183511015611626576004906040906114e16114db8351603c878201528681526114d5816101fd565b83612250565b826121ef565b8151936114ed8561021d565b6000855282820195818751511515918261161b575b505061160d575b8151600090611528906001600160a01b03165b6001600160a01b031690565b8451632d43cbef60e21b815295869182905afa938415610805576000946115f0575b5081810180516001600160a01b03168751608085018051875163ea9cd3bf60e01b87820152999391928a9261158492919060248501611bf9565b0394601f19958681018a52611599908a610254565b516001600160a01b031692516001600160a01b031698519051908651998a958601946115c495611c2f565b0390810185526115d49085610254565b51630556f18360e41b81529283926107dc923060048601611d71565b6116069194503d806000833e6107f68183610254565b923861154a565b611616826120ea565b611509565b511090508138611502565b604051631601fac760e31b8152600490fd5b8061148c61149661149161148c9461148c611487611676997f00000000000000000000000000000000000000000000000000000000000000006119c8565b60409060048251926116878461021d565b6000845280830192835151151580611782575b611774575b80516000906116b6906001600160a01b031661151c565b8351632d43cbef60e21b815294859182905afa92831561080557600093611757575b506020810180519094906001600160a01b0316948151966080840197885197865198899263ea9cd3bf60e01b6020850152602484019261171793611bf9565b0393601f1994858101895261172c9089610254565b516001600160a01b031691516001600160a01b03169251975185519889946115c49460208701611c8a565b61176d9193503d806000833e6107f68183610254565b91386116d8565b61177d816120ea565b61169f565b50602060608201511061169a565b90918161148c6114876117c3937f00000000000000000000000000000000000000000000000000000000000000006119c8565b906117cc61198b565b5060206040830180516001815180151580611888575b61187a575b0190525151116118615761148c826000606061182795015261180881612194565b6114966114db6040516114d58161050f6020820190600a602083019252565b9061183061198b565b50602060608301511015611626576114db61184b9183612250565b604051906118588261021d565b60008252611e15565b604051630251ce0160e31b815260206004820152602490fd5b611883876120ea565b6117e7565b50846060880151106117e2565b908161148c6114876118c7937f00000000000000000000000000000000000000000000000000000000000000006119c8565b906118d061198b565b506020604083018051600181518015158061194f575b611941575b0190525151116118615761148c826000606061192b95015261190c81612194565b6114966114db6040516114d58161050f60208201906003602083019252565b604051906119388261021d565b60008252611f4e565b61194a876120ea565b6118eb565b50846060880151106118e6565b9081602091031261013757516102e2816109d0565b908281018082116112f75782511061013757016020012090565b6040519060a082018281106001600160401b0382111761021857604052606060808360008152600060208201528260408201526000838201520152565b6119d061198b565b506040516119dd81610238565b602091602082526104009283366020850137604051936119fc85610238565b60005b818110611a555750505060008252600083526040519360a085018581106001600160401b03821117610218576040526001600160a01b039182168552166020840152604083015260006060830152608082015290565b606086820184015282016119ff565b611a6c61198b565b5060206040820180516001815180151580611ace575b611ac0575b0190525151116118615760006060820152611aa181612148565b6102e26114db6040516114d58161050f60208201906000602083019252565b611ac9866120ea565b611a87565b5084606087015110611a82565b90611ae461198b565b50602060608301511015611626576114db6102e291604051906020820152602081526114d5816101fd565b611b1761198b565b5060206040820180516001815180151580611b79575b611b6b575b0190525151116118615760006060820152611b4c81612194565b6102e26114db6040516114d58161050f60208201906002602083019252565b611b74866120ea565b611b32565b5084606087015110611b2d565b611b8e61198b565b5060608101602081511015611626576040820190815151600019918282019182116112f757611bbe828551610d96565b519080519384146112f7576001840190526001600160fd1b03831683036112f757611bf592600160fd1b9060031b1c179251610d96565b5290565b6001600160a01b0390911681526060602082018190526102e2939192611c2191840190610f62565b916040818403910152610f96565b93906102e29593611c6191611c6f9460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b908482036060860152610f96565b91637a38480d60e11b608082015260a081840391015261049c565b93906102e29593611c6191611cbc9460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b91631c5fc97360e11b608082015260a081840391015261049c565b93906102e29593611c6191611d099460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b91636f4d5f2f60e11b608082015260a081840391015261049c565b93906102e29593611c6191611d569460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b9163fcd2e38160e01b608082015260a081840391015261049c565b92909493919460a084019060018060a01b0316845260209060a06020860152865180915260c0850191602060c08360051b8801019801926000905b838210611de957505050505084611dce91846102e2969703604086015261049c565b632ded548b60e11b606084015291608081840391015261049c565b90919293988380611e0660019360bf198c82030186528d5161049c565b9b019201920190939291611dac565b60046040820191825151151580611f40575b611f32575b8051600090611e43906001600160a01b031661151c565b604051632d43cbef60e21b815293849182905afa91821561080557600092611f15575b506020810180519093906001600160a01b031693815195608084019687519660405197889263ea9cd3bf60e01b60208501526024840192611ea693611bf9565b0393601f19948581018852611ebb9088610254565b516001600160a01b031691516001600160a01b031692519651604051978894611ee79460208701611cd7565b039081018452611ef79084610254565b604051630556f18360e41b81529283926107dc923060048601611d71565b611f2b9192503d806000833e6107f68183610254565b9038611e66565b611f3b816120ea565b611e2c565b506020606082015110611e27565b6004604082019182515115158061204b575b61203d575b8051600090611f7c906001600160a01b031661151c565b604051632d43cbef60e21b815293849182905afa91821561080557600092612020575b506020810180519093906001600160a01b031693815195608084019687519660405197889263ea9cd3bf60e01b60208501526024840192611fdf93611bf9565b0393601f19948581018852611ff49088610254565b516001600160a01b031691516001600160a01b031692519651604051978894611ee79460208701611d24565b6120369192503d806000833e6107f68183610254565b9038611f9f565b612046816120ea565b611f65565b506020606082015110611f60565b919290156120bb575081511561206d575090565b3b156120765790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156120ce5750805190602001fd5b60405162461bcd60e51b81529081906107dc90600483016104c1565b6040810190815151600019918282019182116112f757606061210d838651610d96565b51910180519384146112f7576001840190526001600160fd1b03831683036112f7576121459260ff60f81b9060031b1c179251610d96565b52565b604081018051516000198082019182116112f7576060612169838551610d96565b51940180519182146112f7576001820190526001600160fd1b038116036112f7576121459151610d96565b6040810190815151600019918282019182116112f75760606121b7838651610d96565b51910180519384146112f7576001840190526001600160fd1b03831683036112f75761214592600160f81b9060031b1c179251610d96565b604081018051519092916000198083019283116112f7576060612213848751610d96565b51920180519182146112f7576001820190526001600160fd1b03811681036112f7576121459360ff60f81b9060f81b169060031b1c179251610d96565b608061227a9193929301519260ff8451169384916001830182526122748383610d96565b52610d96565b5056fea2646970667358221220d0079c3d882566d4f8b428db44b78d6cd6af0cab43c41d234019c1e2e21d205164736f6c634300081900330000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e000000000000000000000000d4416b13d2b3a9abae7acd5d6c2bbdbe2568640100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000e708000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f6170692e73747564696f2e74686567726170682e636f6d2f71756572792f36393239302f656e732d6c696e65612d6d61696e6e65742f76657273696f6e2f6c61746573740000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436101561001257600080fd5b60003560e01c806301ffc9a71461011d57806315f64386146101185780632b7ac3f31461011357806338bf92e6146100d75780633f15457f1461010e5780634062b43f146101095780635bdaa916146101045780636d74e86e146100ff5780638a596ebe146100fa5780639061b923146100f5578063a8e5fbc0146100f0578063d358df77146100eb578063d6ae3cd5146100e6578063de9abe5e146100d7578063f00eebf4146100e1578063f470901a146100dc5763fcd2e381146100d757600080fd5b6104d2565b610cf8565b610c91565b610c56565b610a19565b61098b565b61086d565b610828565b61080a565b61070c565b61066a565b610536565b61035b565b61030a565b61013c565b35906001600160e01b03198216820361013757565b600080fd5b346101375760203660031901126101375760043563ffffffff60e01b81168091036101375761019f90639061b92360e01b81149081156101d6575b81156101c5575b81156101b4575b81156101a3575b5060405190151581529081906020820190565b0390f35b6301ffc9a760e01b1490503861018c565b633c03bafd60e21b81149150610185565b63452cb75f60e11b8114915061017e565b630afb21c360e11b81149150610177565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761021857604052565b6101e7565b602081019081106001600160401b0382111761021857604052565b61042081019081106001600160401b0382111761021857604052565b90601f801991011681019081106001600160401b0382111761021857604052565b6001600160401b03811161021857601f01601f191660200190565b92919261029c82610275565b916102aa6040519384610254565b829481845281830111610137578281602093846000960137010152565b9080601f83011215610137578160206102e293359101610290565b90565b906020828203126101375781356001600160401b038111610137576102e292016102c7565b34610137576020366003190112610137576004356001600160401b03811161013757610346600061034160409336906004016102c7565b611309565b82519182526001600160a01b03166020820152f35b34610137576000366003190112610137576040517f0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f36001600160a01b03168152602090f35b6001600160401b0381116102185760051b60200190565b81601f82011215610137578035916020916103d1846103a0565b936103df6040519586610254565b808552838086019160051b8301019280841161013757848301915b84831061040a5750505050505090565b82356001600160401b03811161013757869161042b848480948901016102c7565b8152019201916103fa565b906040600319830112610137576001600160401b036004358181116101375783610462916004016103b7565b92602435918211610137576102e2916004016102c7565b60005b83811061048c5750506000910152565b818101518382015260200161047c565b906020916104b581518092818552858086019101610479565b601f01601f1916010190565b9060206102e292818152019061049c565b34610137576104e036610436565b508051600110156105315761050f61051d604061019f930151604051928391602080840152604083019061049c565b03601f198101835282610254565b60405191829160208352602083019061049c565b610d80565b34610137576000366003190112610137576040517f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b03168152602090f35b90600182811c921680156105ab575b602083101461059557565b634e487b7160e01b600052602260045260246000fd5b91607f169161058a565b906000916001906001546105c88161057b565b808352926020916001811690811561064557506001146105e9575b50505050565b9293945060016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6926000935b8585106106325750505060209250010190388080806105e3565b8054858501840152938201938101610618565b92505050602093945060ff929192191683830152151560051b010190388080806105e3565b346101375760003660031901126101375761019f60405161051d8161068e816105b5565b0382610254565b9181601f84011215610137578235916001600160401b038311610137576020838186019501011161013757565b6040600319820112610137576001600160401b039160043583811161013757826106ee91600401610695565b939093926024359182116101375761070891600401610695565b9091565b346101375761076b600061073161073a610725366106c2565b949183919301906102e5565b92810190610daa565b95839592979460018060a09b949b1b039283926040519a8b978896879563628e501560e11b87521660048601610ff3565b0392165afa928315610805576000936107e0575b5082519051908181036107ba576107b2846107ac8761050f8760405194859360208501526024840161104f565b306113ce565b602081519101f35b604051632918942560e01b815260048101919091526024810191909152604490fd5b0390fd5b6107fe9193503d806000833e6107f68183610254565b810190610eb8565b913861077f565b611043565b34610137576000366003190112610137576020604051620151808152f35b34610137576020366003190112610137576004356001600160401b03811161013757610858903690600401610695565b505061019f60405161051d8161068e816105b5565b3461013757610341600061089c610883366106c2565b94929095916108956004871015611074565b3691610290565b9290506001600160e01b03196108b283836110b7565b16631d9dabef60e11b8114610977576378e5bf0360e11b811461095a57631674750f60e21b811461093d5763bc1c58d160e01b146109225760405162461bcd60e51b815260206004820152601060248201526f34b73b30b634b21039b2b632b1ba37b960811b6044820152606490fd5b8161093892610930926110e3565b810190611100565b611895565b50816109549261094c926110e3565b810190611125565b90611790565b508161097192610969926110e3565b81019061110f565b90611638565b508161098692610930926110e3565b61144d565b34610137576000366003190112610137576040517f000000000000000000000000d4416b13d2b3a9abae7acd5d6c2bbdbe256864016001600160a01b03168152602090f35b6001600160a01b0381160361013757565b604060031982011261013757600435906001600160401b03821161013757610a0b91600401610695565b90916024356102e2816109d0565b3461013757610a27366109e1565b91610a386000610341368585610290565b506040516302571be360e01b8152600481018290526001600160a01b03602080836024817f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e86165afa92831561080557600093610c35575b507f000000000000000000000000d4416b13d2b3a9abae7acd5d6c2bbdbe256864018216908383168214610b71575b505094610b4c81610b2d7f88781081cc340609705af0f96bf3ba64ea267873444e91725bd072f2af0f44d895610b1d610b5a967f3c68652dbd57659176ef0092991d5753aac3039c3134b7a3eb5689acfaccf62d9b33911614611164565b6000526000602052604060002090565b80546001600160a01b0319166001600160a01b03909216919091179055565b6040519182918686846111e4565b0390a1610b6c6040519283928361120d565b0390a1005b6040516331a9108f60e11b8152600481018690529790935091908390889060249082905afa801561080557610b2d7f88781081cc340609705af0f96bf3ba64ea267873444e91725bd072f2af0f44d895610b1d610b4c9486947f3c68652dbd57659176ef0092991d5753aac3039c3134b7a3eb5689acfaccf62d9c610b5a99600092610c08575b50509750959a5050955050610abf565b610c279250803d10610c2e575b610c1f8183610254565b81019061195c565b3880610bf8565b503d610c15565b819350610c4f9083923d8611610c2e57610c1f8183610254565b9290610a90565b346101375760003660031901126101375760206040517f000000000000000000000000000000000000000000000000000000000000e7088152f35b34610137576044610cb16000610341610ca9366109e1565b503691610290565b60405163e0a0507160e01b81527f000000000000000000000000000000000000000000000000000000000000e70860048201526001600160a01b0390911660248201529050fd5b3461013757610d0636610436565b508051600110156105315761050f610d5f604061019f93015160208151910151906bffffffffffffffffffffffff19918281169160148110610d6b575b50506040805160609290921c6020830152909384925090820190565b604051918291826104c1565b8391925060140360031b1b1616803880610d43565b634e487b7160e01b600052603260045260246000fd5b80518210156105315760209160051b010190565b91909160c081840312610137578035610dc2816109d0565b92602080830135610dd2816109d0565b936001600160401b039160408501358381116101375785019084601f8301121561013757813591610e02836103a0565b92610e106040519485610254565b808452828085019160051b83010191878311610137578301905b828210610e7257505050509360608101358381116101375784610e4e9183016103b7565b93610e5b60808301610122565b9360a0830135908111610137576102e292016102c7565b81358152908301908301610e2a565b90929192610e8e81610275565b91610e9c6040519384610254565b829482845282820111610137576020610eb6930190610479565b565b9060209081838203126101375782516001600160401b039384821161013757019080601f83011215610137578151610eef816103a0565b94604090610f006040519788610254565b828752858088019360051b8601019484861161013757868101935b868510610f2d57505050505050505090565b845183811161013757820186603f82011215610137578891610f5788838886809601519101610e81565b815201940193610f1b565b90815180825260208080930193019160005b828110610f82575050505090565b835185529381019392810192600101610f74565b90808251908181526020809101926020808460051b8301019501936000915b848310610fc55750505050505090565b9091929394958480610fe3600193601f198682030187528a5161049c565b9801930193019194939290610fb5565b9493611030620151809461102260809561103e9560018060a01b03168a5260a060208b015260a08a0190610f62565b9088820360408a0152610f96565b90868203606088015261049c565b930152565b6040513d6000823e3d90fd5b90916110666102e293604084526040840190610f96565b91602081840391015261049c565b1561107b57565b60405162461bcd60e51b81526020600482015260146024820152731c185c985b4819185d18481d1bdbc81cda1bdc9d60621b6044820152606490fd5b6001600160e01b031990358181169392600481106110d457505050565b60040360031b82901b16169150565b909291928360041161013757831161013757600401916003190190565b90816020910312610137573590565b9190826040910312610137576020823592013590565b9190604083820312610137578235926020810135906001600160401b03821161013757019080601f83011215610137578160206102e293359101610290565b1561116b57565b60405162461bcd60e51b815260206004820152602a60248201527f4e6f7420617574686f72697a656420746f207365742074617267657420666f726044820152692074686973206e6f646560b01b6064820152608490fd5b908060209392818452848401376000828201840152601f01601f1916010190565b916020916111fd919594956040855260408501916111c3565b6001600160a01b03909416910152565b9190611221916040845260408401916111c3565b8181036020928301526001805460009392909161123d8361057b565b80835292600181169081156112b6575060011461125c575b5050505090565b9293509060016000527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf692846000945b8386106112a25750505050010138808080611255565b80548587018301529401938590820161128c565b60ff191685840152505090151560051b0101905038808080611255565b634e487b7160e01b600052601160045260246000fd5b90600182018092116112f757565b6112d3565b919082018092116112f757565b9190918051831015610531576020838201015160f81c80156113c2579061134e611349836113436113549561133d896112e9565b86611971565b966112fc565b6112e9565b90611309565b60408051602081019384529081019490945292611374816060810161050f565b51902060008181526020819052604090206001600160a01b03906113a0905b546001600160a01b031690565b166113a9579190565b91506102e2611393836000526000602052604060002090565b50509050600090600090565b906102e291600080604051936113e3856101fd565b601e85527f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000602086015260208151910182855af13d15611445573d9161142883610275565b926114366040519485610254565b83523d6000602085013e612059565b606091612059565b61148c6114966114918361148c61148761149b977f0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f36119c8565b611a64565b611adb565b611b0f565b611b86565b6114a361198b565b5060608101906020908183511015611626576004906040906114e16114db8351603c878201528681526114d5816101fd565b83612250565b826121ef565b8151936114ed8561021d565b6000855282820195818751511515918261161b575b505061160d575b8151600090611528906001600160a01b03165b6001600160a01b031690565b8451632d43cbef60e21b815295869182905afa938415610805576000946115f0575b5081810180516001600160a01b03168751608085018051875163ea9cd3bf60e01b87820152999391928a9261158492919060248501611bf9565b0394601f19958681018a52611599908a610254565b516001600160a01b031692516001600160a01b031698519051908651998a958601946115c495611c2f565b0390810185526115d49085610254565b51630556f18360e41b81529283926107dc923060048601611d71565b6116069194503d806000833e6107f68183610254565b923861154a565b611616826120ea565b611509565b511090508138611502565b604051631601fac760e31b8152600490fd5b8061148c61149661149161148c9461148c611487611676997f0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f36119c8565b60409060048251926116878461021d565b6000845280830192835151151580611782575b611774575b80516000906116b6906001600160a01b031661151c565b8351632d43cbef60e21b815294859182905afa92831561080557600093611757575b506020810180519094906001600160a01b0316948151966080840197885197865198899263ea9cd3bf60e01b6020850152602484019261171793611bf9565b0393601f1994858101895261172c9089610254565b516001600160a01b031691516001600160a01b03169251975185519889946115c49460208701611c8a565b61176d9193503d806000833e6107f68183610254565b91386116d8565b61177d816120ea565b61169f565b50602060608201511061169a565b90918161148c6114876117c3937f0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f36119c8565b906117cc61198b565b5060206040830180516001815180151580611888575b61187a575b0190525151116118615761148c826000606061182795015261180881612194565b6114966114db6040516114d58161050f6020820190600a602083019252565b9061183061198b565b50602060608301511015611626576114db61184b9183612250565b604051906118588261021d565b60008252611e15565b604051630251ce0160e31b815260206004820152602490fd5b611883876120ea565b6117e7565b50846060880151106117e2565b908161148c6114876118c7937f0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f36119c8565b906118d061198b565b506020604083018051600181518015158061194f575b611941575b0190525151116118615761148c826000606061192b95015261190c81612194565b6114966114db6040516114d58161050f60208201906003602083019252565b604051906119388261021d565b60008252611f4e565b61194a876120ea565b6118eb565b50846060880151106118e6565b9081602091031261013757516102e2816109d0565b908281018082116112f75782511061013757016020012090565b6040519060a082018281106001600160401b0382111761021857604052606060808360008152600060208201528260408201526000838201520152565b6119d061198b565b506040516119dd81610238565b602091602082526104009283366020850137604051936119fc85610238565b60005b818110611a555750505060008252600083526040519360a085018581106001600160401b03821117610218576040526001600160a01b039182168552166020840152604083015260006060830152608082015290565b606086820184015282016119ff565b611a6c61198b565b5060206040820180516001815180151580611ace575b611ac0575b0190525151116118615760006060820152611aa181612148565b6102e26114db6040516114d58161050f60208201906000602083019252565b611ac9866120ea565b611a87565b5084606087015110611a82565b90611ae461198b565b50602060608301511015611626576114db6102e291604051906020820152602081526114d5816101fd565b611b1761198b565b5060206040820180516001815180151580611b79575b611b6b575b0190525151116118615760006060820152611b4c81612194565b6102e26114db6040516114d58161050f60208201906002602083019252565b611b74866120ea565b611b32565b5084606087015110611b2d565b611b8e61198b565b5060608101602081511015611626576040820190815151600019918282019182116112f757611bbe828551610d96565b519080519384146112f7576001840190526001600160fd1b03831683036112f757611bf592600160fd1b9060031b1c179251610d96565b5290565b6001600160a01b0390911681526060602082018190526102e2939192611c2191840190610f62565b916040818403910152610f96565b93906102e29593611c6191611c6f9460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b908482036060860152610f96565b91637a38480d60e11b608082015260a081840391015261049c565b93906102e29593611c6191611cbc9460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b91631c5fc97360e11b608082015260a081840391015261049c565b93906102e29593611c6191611d099460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b91636f4d5f2f60e11b608082015260a081840391015261049c565b93906102e29593611c6191611d569460018060a01b03809216885216602087015260c0604087015260c0860190610f62565b9163fcd2e38160e01b608082015260a081840391015261049c565b92909493919460a084019060018060a01b0316845260209060a06020860152865180915260c0850191602060c08360051b8801019801926000905b838210611de957505050505084611dce91846102e2969703604086015261049c565b632ded548b60e11b606084015291608081840391015261049c565b90919293988380611e0660019360bf198c82030186528d5161049c565b9b019201920190939291611dac565b60046040820191825151151580611f40575b611f32575b8051600090611e43906001600160a01b031661151c565b604051632d43cbef60e21b815293849182905afa91821561080557600092611f15575b506020810180519093906001600160a01b031693815195608084019687519660405197889263ea9cd3bf60e01b60208501526024840192611ea693611bf9565b0393601f19948581018852611ebb9088610254565b516001600160a01b031691516001600160a01b031692519651604051978894611ee79460208701611cd7565b039081018452611ef79084610254565b604051630556f18360e41b81529283926107dc923060048601611d71565b611f2b9192503d806000833e6107f68183610254565b9038611e66565b611f3b816120ea565b611e2c565b506020606082015110611e27565b6004604082019182515115158061204b575b61203d575b8051600090611f7c906001600160a01b031661151c565b604051632d43cbef60e21b815293849182905afa91821561080557600092612020575b506020810180519093906001600160a01b031693815195608084019687519660405197889263ea9cd3bf60e01b60208501526024840192611fdf93611bf9565b0393601f19948581018852611ff49088610254565b516001600160a01b031691516001600160a01b031692519651604051978894611ee79460208701611d24565b6120369192503d806000833e6107f68183610254565b9038611f9f565b612046816120ea565b611f65565b506020606082015110611f60565b919290156120bb575081511561206d575090565b3b156120765790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156120ce5750805190602001fd5b60405162461bcd60e51b81529081906107dc90600483016104c1565b6040810190815151600019918282019182116112f757606061210d838651610d96565b51910180519384146112f7576001840190526001600160fd1b03831683036112f7576121459260ff60f81b9060031b1c179251610d96565b52565b604081018051516000198082019182116112f7576060612169838551610d96565b51940180519182146112f7576001820190526001600160fd1b038116036112f7576121459151610d96565b6040810190815151600019918282019182116112f75760606121b7838651610d96565b51910180519384146112f7576001840190526001600160fd1b03831683036112f75761214592600160f81b9060031b1c179251610d96565b604081018051519092916000198083019283116112f7576060612213848751610d96565b51920180519182146112f7576001820190526001600160fd1b03811681036112f7576121459360ff60f81b9060f81b169060031b1c179251610d96565b608061227a9193929301519260ff8451169384916001830182526122748383610d96565b52610d96565b5056fea2646970667358221220d0079c3d882566d4f8b428db44b78d6cd6af0cab43c41d234019c1e2e21d205164736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e000000000000000000000000d4416b13d2b3a9abae7acd5d6c2bbdbe2568640100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000e708000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f6170692e73747564696f2e74686567726170682e636f6d2f71756572792f36393239302f656e732d6c696e65612d6d61696e6e65742f76657273696f6e2f6c61746573740000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _verifier (address): 0x2aD1A39a3b616FB11ac5DB290061A0A5C09771f3
Arg [1] : _ens (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [2] : _nameWrapper (address): 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401
Arg [3] : _graphqlUrl (string): https://api.studio.thegraph.com/query/69290/ens-linea-mainnet/version/latest
Arg [4] : _l2ChainId (uint256): 59144
-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000002ad1a39a3b616fb11ac5db290061a0a5c09771f3
Arg [1] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [2] : 000000000000000000000000d4416b13d2b3a9abae7acd5d6c2bbdbe25686401
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [4] : 000000000000000000000000000000000000000000000000000000000000e708
Arg [5] : 000000000000000000000000000000000000000000000000000000000000004c
Arg [6] : 68747470733a2f2f6170692e73747564696f2e74686567726170682e636f6d2f
Arg [7] : 71756572792f36393239302f656e732d6c696e65612d6d61696e6e65742f7665
Arg [8] : 7273696f6e2f6c61746573740000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.