Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 263 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Approval For... | 20200067 | 13 days ago | IN | 0 ETH | 0.00011963 | ||||
Set Approval For... | 18802649 | 209 days ago | IN | 0 ETH | 0.00094299 | ||||
Set Approval For... | 17646767 | 371 days ago | IN | 0 ETH | 0.00033106 | ||||
Set Approval For... | 17511651 | 390 days ago | IN | 0 ETH | 0.00042259 | ||||
Set Approval For... | 17148400 | 441 days ago | IN | 0 ETH | 0.00082773 | ||||
Set Approval For... | 16863847 | 482 days ago | IN | 0 ETH | 0.00075564 | ||||
Set Approval For... | 16628794 | 515 days ago | IN | 0 ETH | 0.00058632 | ||||
Set Approval For... | 16586866 | 520 days ago | IN | 0 ETH | 0.00082341 | ||||
Set Approval For... | 16536004 | 528 days ago | IN | 0 ETH | 0.00062733 | ||||
Set Approval For... | 16517223 | 530 days ago | IN | 0 ETH | 0.00063639 | ||||
Set Approval For... | 16487312 | 534 days ago | IN | 0 ETH | 0.00056338 | ||||
Set Approval For... | 16485975 | 535 days ago | IN | 0 ETH | 0.00055693 | ||||
Set Approval For... | 16485182 | 535 days ago | IN | 0 ETH | 0.0005931 | ||||
Set Approval For... | 16419997 | 544 days ago | IN | 0 ETH | 0.00095548 | ||||
Set Approval For... | 16419701 | 544 days ago | IN | 0 ETH | 0.00070391 | ||||
Set Approval For... | 16417612 | 544 days ago | IN | 0 ETH | 0.00072457 | ||||
Set Approval For... | 16417528 | 544 days ago | IN | 0 ETH | 0.00067839 | ||||
Set Approval For... | 16417289 | 544 days ago | IN | 0 ETH | 0.00067839 | ||||
Set Approval For... | 16366116 | 551 days ago | IN | 0 ETH | 0.00048645 | ||||
Set Approval For... | 16357803 | 552 days ago | IN | 0 ETH | 0.00051023 | ||||
Set Approval For... | 16357084 | 553 days ago | IN | 0 ETH | 0.00067116 | ||||
Set Approval For... | 16336579 | 555 days ago | IN | 0 ETH | 0.00093611 | ||||
Set Approval For... | 16303864 | 560 days ago | IN | 0 ETH | 0.0006592 | ||||
Set Approval For... | 16279191 | 563 days ago | IN | 0 ETH | 0.00075691 | ||||
Set Approval For... | 16273482 | 564 days ago | IN | 0 ETH | 0.00066721 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
EarthLabResolver
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "@ensdomains/ens-contracts/contracts/resolvers/PublicResolver.sol"; contract EarthLabResolver is PublicResolver { constructor(INameWrapper wrapper) PublicResolver( ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e), wrapper, 0x0000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000 ) {} }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../registry/ENS.sol"; import "./profiles/ABIResolver.sol"; import "./profiles/AddrResolver.sol"; import "./profiles/ContentHashResolver.sol"; import "./profiles/DNSResolver.sol"; import "./profiles/InterfaceResolver.sol"; import "./profiles/NameResolver.sol"; import "./profiles/PubkeyResolver.sol"; import "./profiles/TextResolver.sol"; import "./Multicallable.sol"; interface INameWrapper { function ownerOf(uint256 id) external view returns (address); } /** * A simple resolver anyone can use; only allows the owner of a node to set its * address. */ contract PublicResolver is Multicallable, ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver { ENS immutable ens; INameWrapper immutable nameWrapper; address immutable trustedETHController; address immutable trustedReverseRegistrar; /** * A mapping of operators. An address that is authorised for an address * may make any changes to the name that the owner could, but may not update * the set of authorisations. * (owner, operator) => approved */ mapping(address => mapping(address => bool)) private _operatorApprovals; // Logged when an operator is added or removed. event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); constructor( ENS _ens, INameWrapper wrapperAddress, address _trustedETHController, address _trustedReverseRegistrar ) { ens = _ens; nameWrapper = wrapperAddress; trustedETHController = _trustedETHController; trustedReverseRegistrar = _trustedReverseRegistrar; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) external { require( msg.sender != operator, "ERC1155: setting approval status for self" ); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view returns (bool) { return _operatorApprovals[account][operator]; } function isAuthorised(bytes32 node) internal view override returns (bool) { if ( msg.sender == trustedETHController || msg.sender == trustedReverseRegistrar ) { return true; } address owner = ens.owner(node); if (owner == address(nameWrapper)) { owner = nameWrapper.ownerOf(uint256(node)); } return owner == msg.sender || isApprovedForAll(owner, msg.sender); } function supportsInterface(bytes4 interfaceID) public view override( Multicallable, ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver ) returns (bool) { return super.supportsInterface(interfaceID); } }
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; import "./IABIResolver.sol"; import "../ResolverBase.sol"; abstract contract ABIResolver is IABIResolver, ResolverBase { mapping(bytes32=>mapping(uint256=>bytes)) abis; /** * Sets the ABI associated with an ENS node. * Nodes may have one ABI of each content type. To remove an ABI, set it to * the empty string. * @param node The node to update. * @param contentType The content type of the ABI * @param data The ABI data. */ function setABI(bytes32 node, uint256 contentType, bytes calldata data) virtual external authorised(node) { // Content types must be powers of 2 require(((contentType - 1) & contentType) == 0); abis[node][contentType] = data; emit ABIChanged(node, contentType); } /** * Returns the ABI associated with an ENS node. * Defined in EIP205. * @param node The ENS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) virtual override external view returns (uint256, bytes memory) { mapping(uint256=>bytes) storage abiset = abis[node]; for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) { if ((contentType & contentTypes) != 0 && abiset[contentType].length > 0) { return (contentType, abiset[contentType]); } } return (0, bytes("")); } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IABIResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./IAddrResolver.sol"; import "./IAddressResolver.sol"; abstract contract AddrResolver is IAddrResolver, IAddressResolver, ResolverBase { uint constant private COIN_TYPE_ETH = 60; mapping(bytes32=>mapping(uint=>bytes)) _addresses; /** * Sets the address associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param a The address to set. */ function setAddr(bytes32 node, address a) virtual external authorised(node) { setAddr(node, COIN_TYPE_ETH, addressToBytes(a)); } /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) virtual override public view returns (address payable) { bytes memory a = addr(node, COIN_TYPE_ETH); if(a.length == 0) { return payable(0); } return bytesToAddress(a); } function setAddr(bytes32 node, uint coinType, bytes memory a) virtual public authorised(node) { emit AddressChanged(node, coinType, a); if(coinType == COIN_TYPE_ETH) { emit AddrChanged(node, bytesToAddress(a)); } _addresses[node][coinType] = a; } function addr(bytes32 node, uint coinType) virtual override public view returns(bytes memory) { return _addresses[node][coinType]; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IAddrResolver).interfaceId || interfaceID == type(IAddressResolver).interfaceId || super.supportsInterface(interfaceID); } function bytesToAddress(bytes memory b) internal pure returns(address payable a) { require(b.length == 20); assembly { a := div(mload(add(b, 32)), exp(256, 12)) } } function addressToBytes(address a) internal pure returns(bytes memory b) { b = new bytes(20); assembly { mstore(add(b, 32), mul(a, exp(256, 12))) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./IContentHashResolver.sol"; abstract contract ContentHashResolver is IContentHashResolver, ResolverBase { mapping(bytes32=>bytes) hashes; /** * Sets the contenthash associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The contenthash to set */ function setContenthash(bytes32 node, bytes calldata hash) virtual external authorised(node) { hashes[node] = hash; emit ContenthashChanged(node, hash); } /** * Returns the contenthash associated with an ENS node. * @param node The ENS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) virtual external override view returns (bytes memory) { return hashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IContentHashResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "../../dnssec-oracle/RRUtils.sol"; import "./IDNSRecordResolver.sol"; import "./IDNSZoneResolver.sol"; abstract contract DNSResolver is IDNSRecordResolver, IDNSZoneResolver, ResolverBase { using RRUtils for *; using BytesUtils for bytes; // Zone hashes for the domains. // A zone hash is an EIP-1577 content hash in binary format that should point to a // resource containing a single zonefile. // node => contenthash mapping(bytes32=>bytes) private zonehashes; // Version the mapping for each zone. This allows users who have lost // track of their entries to effectively delete an entire zone by bumping // the version number. // node => version mapping(bytes32=>uint256) private versions; // The records themselves. Stored as binary RRSETs // node => version => name => resource => data mapping(bytes32=>mapping(uint256=>mapping(bytes32=>mapping(uint16=>bytes)))) private records; // Count of number of entries for a given name. Required for DNS resolvers // when resolving wildcards. // node => version => name => number of records mapping(bytes32=>mapping(uint256=>mapping(bytes32=>uint16))) private nameEntriesCount; /** * Set one or more DNS records. Records are supplied in wire-format. * Records with the same node/name/resource must be supplied one after the * other to ensure the data is updated correctly. For example, if the data * was supplied: * a.example.com IN A 1.2.3.4 * a.example.com IN A 5.6.7.8 * www.example.com IN CNAME a.example.com. * then this would store the two A records for a.example.com correctly as a * single RRSET, however if the data was supplied: * a.example.com IN A 1.2.3.4 * www.example.com IN CNAME a.example.com. * a.example.com IN A 5.6.7.8 * then this would store the first A record, the CNAME, then the second A * record which would overwrite the first. * * @param node the namehash of the node for which to set the records * @param data the DNS wire format records to set */ function setDNSRecords(bytes32 node, bytes calldata data) virtual external authorised(node) { uint16 resource = 0; uint256 offset = 0; bytes memory name; bytes memory value; bytes32 nameHash; // Iterate over the data to add the resource records for (RRUtils.RRIterator memory iter = data.iterateRRs(0); !iter.done(); iter.next()) { if (resource == 0) { resource = iter.dnstype; name = iter.name(); nameHash = keccak256(abi.encodePacked(name)); value = bytes(iter.rdata()); } else { bytes memory newName = iter.name(); if (resource != iter.dnstype || !name.equals(newName)) { setDNSRRSet(node, name, resource, data, offset, iter.offset - offset, value.length == 0); resource = iter.dnstype; offset = iter.offset; name = newName; nameHash = keccak256(name); value = bytes(iter.rdata()); } } } if (name.length > 0) { setDNSRRSet(node, name, resource, data, offset, data.length - offset, value.length == 0); } } /** * Obtain a DNS record. * @param node the namehash of the node for which to fetch the record * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types * @return the DNS record in wire format if present, otherwise empty */ function dnsRecord(bytes32 node, bytes32 name, uint16 resource) virtual override public view returns (bytes memory) { return records[node][versions[node]][name][resource]; } /** * Check if a given node has records. * @param node the namehash of the node for which to check the records * @param name the namehash of the node for which to check the records */ function hasDNSRecords(bytes32 node, bytes32 name) virtual public view returns (bool) { return (nameEntriesCount[node][versions[node]][name] != 0); } /** * Clear all information for a DNS zone. * @param node the namehash of the node for which to clear the zone */ function clearDNSZone(bytes32 node) virtual public authorised(node) { versions[node]++; emit DNSZoneCleared(node); } /** * setZonehash sets the hash for the zone. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The zonehash to set */ function setZonehash(bytes32 node, bytes calldata hash) virtual external authorised(node) { bytes memory oldhash = zonehashes[node]; zonehashes[node] = hash; emit DNSZonehashChanged(node, oldhash, hash); } /** * zonehash obtains the hash for the zone. * @param node The ENS node to query. * @return The associated contenthash. */ function zonehash(bytes32 node) virtual override external view returns (bytes memory) { return zonehashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IDNSRecordResolver).interfaceId || interfaceID == type(IDNSZoneResolver).interfaceId || super.supportsInterface(interfaceID); } function setDNSRRSet( bytes32 node, bytes memory name, uint16 resource, bytes memory data, uint256 offset, uint256 size, bool deleteRecord) private { uint256 version = versions[node]; bytes32 nameHash = keccak256(name); bytes memory rrData = data.substring(offset, size); if (deleteRecord) { if (records[node][version][nameHash][resource].length != 0) { nameEntriesCount[node][version][nameHash]--; } delete(records[node][version][nameHash][resource]); emit DNSRecordDeleted(node, name, resource); } else { if (records[node][version][nameHash][resource].length == 0) { nameEntriesCount[node][version][nameHash]++; } records[node][version][nameHash][resource] = rrData; emit DNSRecordChanged(node, name, resource, rrData); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "../ResolverBase.sol"; import "./AddrResolver.sol"; import "./IInterfaceResolver.sol"; abstract contract InterfaceResolver is IInterfaceResolver, AddrResolver { mapping(bytes32=>mapping(bytes4=>address)) interfaces; /** * Sets an interface associated with a name. * Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support. * @param node The node to update. * @param interfaceID The EIP 165 interface ID. * @param implementer The address of a contract that implements this interface for this node. */ function setInterface(bytes32 node, bytes4 interfaceID, address implementer) virtual external authorised(node) { interfaces[node][interfaceID] = implementer; emit InterfaceChanged(node, interfaceID, implementer); } /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The ENS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) virtual override external view returns (address) { address implementer = interfaces[node][interfaceID]; if(implementer != address(0)) { return implementer; } address a = addr(node); if(a == address(0)) { return address(0); } (bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", type(IERC165).interfaceId)); if(!success || returnData.length < 32 || returnData[31] == 0) { // EIP 165 not supported by target return address(0); } (success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID)); if(!success || returnData.length < 32 || returnData[31] == 0) { // Specified interface not supported by target return address(0); } return a; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IInterfaceResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./INameResolver.sol"; abstract contract NameResolver is INameResolver, ResolverBase { mapping(bytes32=>string) names; /** * Sets the name associated with an ENS node, for reverse records. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. */ function setName(bytes32 node, string calldata newName) virtual external authorised(node) { names[node] = newName; emit NameChanged(node, newName); } /** * Returns the name associated with an ENS node, for reverse records. * Defined in EIP181. * @param node The ENS node to query. * @return The associated name. */ function name(bytes32 node) virtual override external view returns (string memory) { return names[node]; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(INameResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./IPubkeyResolver.sol"; abstract contract PubkeyResolver is IPubkeyResolver, ResolverBase { struct PublicKey { bytes32 x; bytes32 y; } mapping(bytes32=>PublicKey) pubkeys; /** * Sets the SECP256k1 public key associated with an ENS node. * @param node The ENS node to query * @param x the X coordinate of the curve point for the public key. * @param y the Y coordinate of the curve point for the public key. */ function setPubkey(bytes32 node, bytes32 x, bytes32 y) virtual external authorised(node) { pubkeys[node] = PublicKey(x, y); emit PubkeyChanged(node, x, y); } /** * Returns the SECP256k1 public key associated with an ENS node. * Defined in EIP 619. * @param node The ENS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) virtual override external view returns (bytes32 x, bytes32 y) { return (pubkeys[node].x, pubkeys[node].y); } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(IPubkeyResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./ITextResolver.sol"; abstract contract TextResolver is ITextResolver, ResolverBase { mapping(bytes32=>mapping(string=>string)) texts; /** * Sets the text data associated with an ENS node and key. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param key The key to set. * @param value The text data value to set. */ function setText(bytes32 node, string calldata key, string calldata value) virtual external authorised(node) { texts[node][key] = value; emit TextChanged(node, key, key); } /** * 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) virtual override external view returns (string memory) { return texts[node][key]; } function supportsInterface(bytes4 interfaceID) virtual override public view returns(bool) { return interfaceID == type(ITextResolver).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "./IMulticallable.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; abstract contract Multicallable is IMulticallable, ERC165 { function multicall(bytes[] calldata data) external override returns(bytes[] memory results) { results = new bytes[](data.length); for(uint i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); require(success); results[i] = result; } return results; } function supportsInterface(bytes4 interfaceID) public override virtual view returns(bool) { return interfaceID == type(IMulticallable).interfaceId || super.supportsInterface(interfaceID); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "./IABIResolver.sol"; import "../ResolverBase.sol"; interface IABIResolver { event ABIChanged(bytes32 indexed node, uint256 indexed contentType); /** * Returns the ABI associated with an ENS node. * Defined in EIP205. * @param node The ENS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; abstract contract ResolverBase is ERC165 { function isAuthorised(bytes32 node) internal virtual view returns(bool); modifier authorised(bytes32 node) { require(isAuthorised(node)); _; } }
// 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.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 for the new (multicoin) addr function. */ interface IAddressResolver { event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); function addr(bytes32 node, uint coinType) external view returns(bytes memory); }
// 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); }
pragma solidity ^0.8.4; import "./BytesUtils.sol"; import "@ensdomains/buffer/contracts/Buffer.sol"; /** * @dev RRUtils is a library that provides utilities for parsing DNS resource records. */ library RRUtils { using BytesUtils for *; using Buffer for *; /** * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The length of the DNS name at 'offset', in bytes. */ function nameLength(bytes memory self, uint offset) internal pure returns(uint) { uint idx = offset; while (true) { assert(idx < self.length); uint labelLen = self.readUint8(idx); idx += labelLen + 1; if (labelLen == 0) { break; } } return idx - offset; } /** * @dev Returns a DNS format name at the specified offset of self. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return ret The name. */ function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) { uint len = nameLength(self, offset); return self.substring(offset, len); } /** * @dev Returns the number of labels in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The number of labels in the DNS name at 'offset', in bytes. */ function labelCount(bytes memory self, uint offset) internal pure returns(uint) { uint count = 0; while (true) { assert(offset < self.length); uint labelLen = self.readUint8(offset); offset += labelLen + 1; if (labelLen == 0) { break; } count += 1; } return count; } uint constant RRSIG_TYPE = 0; uint constant RRSIG_ALGORITHM = 2; uint constant RRSIG_LABELS = 3; uint constant RRSIG_TTL = 4; uint constant RRSIG_EXPIRATION = 8; uint constant RRSIG_INCEPTION = 12; uint constant RRSIG_KEY_TAG = 16; uint constant RRSIG_SIGNER_NAME = 18; struct SignedSet { uint16 typeCovered; uint8 algorithm; uint8 labels; uint32 ttl; uint32 expiration; uint32 inception; uint16 keytag; bytes signerName; bytes data; bytes name; } function readSignedSet(bytes memory data) internal pure returns(SignedSet memory self) { self.typeCovered = data.readUint16(RRSIG_TYPE); self.algorithm = data.readUint8(RRSIG_ALGORITHM); self.labels = data.readUint8(RRSIG_LABELS); self.ttl = data.readUint32(RRSIG_TTL); self.expiration = data.readUint32(RRSIG_EXPIRATION); self.inception = data.readUint32(RRSIG_INCEPTION); self.keytag = data.readUint16(RRSIG_KEY_TAG); self.signerName = readName(data, RRSIG_SIGNER_NAME); self.data = data.substring(RRSIG_SIGNER_NAME + self.signerName.length, data.length - RRSIG_SIGNER_NAME - self.signerName.length); } function rrs(SignedSet memory rrset) internal pure returns(RRIterator memory) { return iterateRRs(rrset.data, 0); } /** * @dev An iterator over resource records. */ struct RRIterator { bytes data; uint offset; uint16 dnstype; uint16 class; uint32 ttl; uint rdataOffset; uint nextOffset; } /** * @dev Begins iterating over resource records. * @param self The byte string to read from. * @param offset The offset to start reading at. * @return ret An iterator object. */ function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) { ret.data = self; ret.nextOffset = offset; next(ret); } /** * @dev Returns true iff there are more RRs to iterate. * @param iter The iterator to check. * @return True iff the iterator has finished. */ function done(RRIterator memory iter) internal pure returns(bool) { return iter.offset >= iter.data.length; } /** * @dev Moves the iterator to the next resource record. * @param iter The iterator to advance. */ function next(RRIterator memory iter) internal pure { iter.offset = iter.nextOffset; if (iter.offset >= iter.data.length) { return; } // Skip the name uint off = iter.offset + nameLength(iter.data, iter.offset); // Read type, class, and ttl iter.dnstype = iter.data.readUint16(off); off += 2; iter.class = iter.data.readUint16(off); off += 2; iter.ttl = iter.data.readUint32(off); off += 4; // Read the rdata uint rdataLength = iter.data.readUint16(off); off += 2; iter.rdataOffset = off; iter.nextOffset = off + rdataLength; } /** * @dev Returns the name of the current record. * @param iter The iterator. * @return A new bytes object containing the owner name from the RR. */ function name(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset)); } /** * @dev Returns the rdata portion of the current record. * @param iter The iterator. * @return A new bytes object containing the RR's RDATA. */ function rdata(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset); } uint constant DNSKEY_FLAGS = 0; uint constant DNSKEY_PROTOCOL = 2; uint constant DNSKEY_ALGORITHM = 3; uint constant DNSKEY_PUBKEY = 4; struct DNSKEY { uint16 flags; uint8 protocol; uint8 algorithm; bytes publicKey; } function readDNSKEY(bytes memory data, uint offset, uint length) internal pure returns(DNSKEY memory self) { self.flags = data.readUint16(offset + DNSKEY_FLAGS); self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL); self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM); self.publicKey = data.substring(offset + DNSKEY_PUBKEY, length - DNSKEY_PUBKEY); } uint constant DS_KEY_TAG = 0; uint constant DS_ALGORITHM = 2; uint constant DS_DIGEST_TYPE = 3; uint constant DS_DIGEST = 4; struct DS { uint16 keytag; uint8 algorithm; uint8 digestType; bytes digest; } function readDS(bytes memory data, uint offset, uint length) internal pure returns(DS memory self) { self.keytag = data.readUint16(offset + DS_KEY_TAG); self.algorithm = data.readUint8(offset + DS_ALGORITHM); self.digestType = data.readUint8(offset + DS_DIGEST_TYPE); self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST); } struct NSEC3 { uint8 hashAlgorithm; uint8 flags; uint16 iterations; bytes salt; bytes32 nextHashedOwnerName; bytes typeBitmap; } uint constant NSEC3_HASH_ALGORITHM = 0; uint constant NSEC3_FLAGS = 1; uint constant NSEC3_ITERATIONS = 2; uint constant NSEC3_SALT_LENGTH = 4; uint constant NSEC3_SALT = 5; function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) { uint end = offset + length; self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM); self.flags = data.readUint8(offset + NSEC3_FLAGS); self.iterations = data.readUint16(offset + NSEC3_ITERATIONS); uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH); offset = offset + NSEC3_SALT; self.salt = data.substring(offset, saltLength); offset += saltLength; uint8 nextLength = data.readUint8(offset); require(nextLength <= 32); offset += 1; self.nextHashedOwnerName = data.readBytesN(offset, nextLength); offset += nextLength; self.typeBitmap = data.substring(offset, end - offset); } function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) { return checkTypeBitmap(self.typeBitmap, 0, rrtype); } /** * @dev Checks if a given RR type exists in a type bitmap. * @param bitmap The byte string to read the type bitmap from. * @param offset The offset to start reading at. * @param rrtype The RR type to check for. * @return True if the type is found in the bitmap, false otherwise. */ function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) { uint8 typeWindow = uint8(rrtype >> 8); uint8 windowByte = uint8((rrtype & 0xff) / 8); uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7))); for (uint off = offset; off < bitmap.length;) { uint8 window = bitmap.readUint8(off); uint8 len = bitmap.readUint8(off + 1); if (typeWindow < window) { // We've gone past our window; it's not here. return false; } else if (typeWindow == window) { // Check this type bitmap if (len <= windowByte) { // Our type is past the end of the bitmap return false; } return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0; } else { // Skip this type bitmap off += len + 2; } } return false; } function compareNames(bytes memory self, bytes memory other) internal pure returns (int) { if (self.equals(other)) { return 0; } uint off; uint otheroff; uint prevoff; uint otherprevoff; uint counts = labelCount(self, 0); uint othercounts = labelCount(other, 0); // Keep removing labels from the front of the name until both names are equal length while (counts > othercounts) { prevoff = off; off = progress(self, off); counts--; } while (othercounts > counts) { otherprevoff = otheroff; otheroff = progress(other, otheroff); othercounts--; } // Compare the last nonequal labels to each other while (counts > 0 && !self.equals(off, other, otheroff)) { prevoff = off; off = progress(self, off); otherprevoff = otheroff; otheroff = progress(other, otheroff); counts -= 1; } if (off == 0) { return -1; } if(otheroff == 0) { return 1; } return self.compare(prevoff + 1, self.readUint8(prevoff), other, otherprevoff + 1, other.readUint8(otherprevoff)); } /** * @dev Compares two serial numbers using RFC1982 serial number math. */ function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) { return int32(i1) - int32(i2) >= 0; } function progress(bytes memory body, uint off) internal pure returns(uint) { return off + 1 + body.readUint8(off); } /** * @dev Computes the keytag for a chunk of data. * @param data The data to compute a keytag for. * @return The computed key tag. */ function computeKeytag(bytes memory data) internal pure returns (uint16) { /* This function probably deserves some explanation. * The DNSSEC keytag function is a checksum that relies on summing up individual bytes * from the input string, with some mild bitshifting. Here's a Naive solidity implementation: * * function computeKeytag(bytes memory data) internal pure returns (uint16) { * uint ac; * for (uint i = 0; i < data.length; i++) { * ac += i & 1 == 0 ? uint16(data.readUint8(i)) << 8 : data.readUint8(i); * } * return uint16(ac + (ac >> 16)); * } * * The EVM, with its 256 bit words, is exceedingly inefficient at doing byte-by-byte operations; * the code above, on reasonable length inputs, consumes over 100k gas. But we can make the EVM's * large words work in our favour. * * The code below works by treating the input as a series of 256 bit words. It first masks out * even and odd bytes from each input word, adding them to two separate accumulators `ac1` and `ac2`. * The bytes are separated by empty bytes, so as long as no individual sum exceeds 2^16-1, we're * effectively summing 16 different numbers with each EVM ADD opcode. * * Once it's added up all the inputs, it has to add all the 16 bit values in `ac1` and `ac2` together. * It does this using the same trick - mask out every other value, shift to align them, add them together. * After the first addition on both accumulators, there's enough room to add the two accumulators together, * and the remaining sums can be done just on ac1. */ unchecked { require(data.length <= 8192, "Long keys not permitted"); uint ac1; uint ac2; for(uint i = 0; i < data.length + 31; i += 32) { uint word; assembly { word := mload(add(add(data, 32), i)) } if(i + 32 > data.length) { uint unused = 256 - (data.length - i) * 8; word = (word >> unused) << unused; } ac1 += (word & 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >> 8; ac2 += (word & 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF); } ac1 = (ac1 & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) + ((ac1 & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16); ac2 = (ac2 & 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) + ((ac2 & 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >> 16); ac1 = (ac1 << 8) + ac2; ac1 = (ac1 & 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) + ((ac1 & 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >> 32); ac1 = (ac1 & 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) + ((ac1 & 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >> 64); ac1 = (ac1 & 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + (ac1 >> 128); ac1 += (ac1 >> 16) & 0xFFFF; return uint16(ac1); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IDNSRecordResolver { // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated. event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record); // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted. event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource); // DNSZoneCleared is emitted whenever a given node's zone information is cleared. event DNSZoneCleared(bytes32 indexed node); /** * Obtain a DNS record. * @param node the namehash of the node for which to fetch the record * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types * @return the DNS record in wire format if present, otherwise empty */ function dnsRecord(bytes32 node, bytes32 name, uint16 resource) external view returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IDNSZoneResolver { // DNSZonehashChanged is emitted whenever a given node's zone hash is updated. event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash); /** * zonehash obtains the hash for the zone. * @param node The ENS node to query. * @return The associated contenthash. */ function zonehash(bytes32 node) external view returns (bytes memory); }
pragma solidity ^0.8.4; library BytesUtils { /* * @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, uint offset, uint 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 (int) { 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, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) { uint shortest = len; if (otherlen < len) shortest = otherlen; uint selfptr; uint otherptr; assembly { selfptr := add(self, add(offset, 32)) otherptr := add(other, add(otheroffset, 32)) } for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask; if (shortest > 32) { mask = type(uint256).max; } else { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } int diff = int(a & mask) - int(b & mask); if (diff != 0) return diff; } selfptr += 32; otherptr += 32; } return int(len) - int(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, uint offset, bytes memory other, uint otherOffset, uint 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, uint offset, bytes memory other, uint 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, uint 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, uint 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, uint 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, uint 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, uint 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, uint 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, uint idx, uint 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(uint dest, uint src, uint 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 { uint 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, uint offset, uint len) internal pure returns(bytes memory) { require(offset + len <= self.length); bytes memory ret = new bytes(len); uint dest; uint 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, uint off, uint len) internal pure returns(bytes32) { require(len <= 52); uint ret = 0; uint8 decoded; for(uint i = 0; i < len; i++) { bytes1 char = self[off + i]; require(char >= 0x30 && char <= 0x7A); decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]); require(decoded <= 0x20); if(i == len - 1) { break; } ret = (ret << 5) | decoded; } uint 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)); } }
pragma solidity ^0.8.4; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns(buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns(uint) { if (a > b) { return a; } return b; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } return buf; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } unchecked { uint mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IInterfaceResolver { event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer); /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The ENS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface INameResolver { event NameChanged(bytes32 indexed node, string name); /** * Returns the name associated with an ENS node, for reverse records. * Defined in EIP181. * @param node The ENS node to query. * @return The associated name. */ function name(bytes32 node) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface IPubkeyResolver { event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); /** * Returns the SECP256k1 public key associated with an ENS node. * Defined in EIP 619. * @param node The ENS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface ITextResolver { event TextChanged(bytes32 indexed node, string indexed indexedKey, string key); /** * 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.4; interface IMulticallable { function multicall(bytes[] calldata data) external returns(bytes[] memory results); }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract INameWrapper","name":"wrapper","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"lastzonehash","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"zonehash","type":"bytes"}],"name":"DNSZonehashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"newName","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setZonehash","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":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"zonehash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b506040516200299238038062002992833981016040819052620000359162000064565b6e0c2e074ec69a0dfb2997ba6c7d2e1e6080526001600160a01b031660a052600060c081905260e05262000096565b6000602082840312156200007757600080fd5b81516001600160a01b03811681146200008f57600080fd5b9392505050565b60805160a05160c05160e0516128bb620000d760003960006114f7015260006114c50152600081816115cf01526116350152600061155801526128bb6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806377372213116100ee578063bc1c58d111610097578063d5fa2b0011610071578063d5fa2b0014610403578063e59d895d14610416578063e985e9c514610429578063f1cb7e061461046557600080fd5b8063bc1c58d1146103a0578063c8690233146103b3578063ce3decdc146103f057600080fd5b8063a8fa5682116100c8578063a8fa56821461035a578063ac9650d81461036d578063ad5780af1461038d57600080fd5b806377372213146103215780638b95dd7114610334578063a22cb4651461034757600080fd5b8063304e6ade1161015b57806359d1d43c1161013557806359d1d43c146102c85780635c98042b146102e8578063623195b0146102fb578063691f34311461030e57600080fd5b8063304e6ade146102625780633b3b57de146102755780634cbf6ba41461028857600080fd5b8063124a319c1161018c578063124a319c146102035780632203ab561461022e57806329cd62ea1461024f57600080fd5b806301ffc9a7146101b35780630af179d7146101db57806310f13a8c146101f0575b600080fd5b6101c66101c13660046120d3565b610478565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612130565b610489565b005b6101ee6101fe36600461217c565b610677565b6102166102113660046121f6565b610724565b6040516001600160a01b0390911681526020016101d2565b61024161023c366004612222565b6109b6565b6040516101d29291906122a0565b6101ee61025d3660046122b9565b610ad1565b6101ee610270366004612130565b610b51565b6102166102833660046122e5565b610bb0565b6101c6610296366004612222565b600091825260066020908152604080842060048352818520548552825280842092845291905290205461ffff16151590565b6102db6102d6366004612130565b610be2565b6040516101d291906122fe565b6102db6102f63660046122e5565b610ca7565b6101ee610309366004612311565b610d49565b6102db61031c3660046122e5565b610dca565b6101ee61032f366004612130565b610de7565b6101ee61034236600461237a565b610e46565b6101ee610355366004612453565b610f10565b6102db610368366004612491565b611018565b61038061037b3660046124d1565b61105b565b6040516101d29190612546565b6101ee61039b3660046122e5565b611176565b6102db6103ae3660046122e5565b6111d7565b6103db6103c13660046122e5565b600090815260096020526040902080546001909101549091565b604080519283526020830191909152016101d2565b6101ee6103fe366004612130565b6111f4565b6101ee6104113660046125a8565b611300565b6101ee6104243660046125cd565b611327565b6101c6610437366004612602565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205460ff1690565b6102db610473366004612222565b6113cc565b60006104838261147a565b92915050565b82610493816114b8565b61049c57600080fd5b6000806060806000806104e960008a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506116e99050565b90505b80515160208201511015610612578561ffff1660000361055157806040015195506105168161174a565b9350836040516020016105299190612630565b60405160208183030381529060405280519060200120915061054a8161176b565b9250610604565b600061055c8261174a565b9050816040015161ffff168761ffff16141580610580575061057e8582611787565b155b15610602576105db8b86898d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505060208801518c91506105d3908290612662565b8a51156117a5565b8160400151965081602001519550809450848051906020012092506105ff8261176b565b93505b505b61060d816119e8565b6104ec565b5082511561066c5761066c8984878b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061066491508290508e612662565b8851156117a5565b505050505050505050565b84610681816114b8565b61068a57600080fd5b8282600a600089815260200190815260200160002087876040516106af929190612679565b9081526040519081900360200190206106c9929091611f6c565b5084846040516106da929190612679565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a755087876040516107149291906126b2565b60405180910390a3505050505050565b60008281526007602090815260408083206001600160e01b0319851684529091528120546001600160a01b0316801561075e579050610483565b600061076985610bb0565b90506001600160a01b03811661078457600092505050610483565b6040516301ffc9a760e01b602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b179052516107f19190612630565b600060405180830381855afa9150503d806000811461082c576040519150601f19603f3d011682016040523d82523d6000602084013e610831565b606091505b5091509150811580610844575060208151105b80610886575080601f8151811061085d5761085d6126c6565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016155b15610898576000945050505050610483565b6040516001600160e01b0319871660248201526001600160a01b0384169060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b179052516109039190612630565b600060405180830381855afa9150503d806000811461093e576040519150601f19603f3d011682016040523d82523d6000602084013e610943565b606091505b509092509050811580610957575060208151105b80610999575080601f81518110610970576109706126c6565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016155b156109ab576000945050505050610483565b509095945050505050565b600082815260208190526040812060609060015b848111610ab157808516158015906109fa5750600081815260208390526040812080546109f6906126dc565b9050115b15610aa95780826000838152602001908152602001600020808054610a1e906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4a906126dc565b8015610a975780601f10610a6c57610100808354040283529160200191610a97565b820191906000526020600020905b815481529060010190602001808311610a7a57829003601f168201915b50505050509050935093505050610aca565b60011b6109ca565b5060006040518060200160405280600081525092509250505b9250929050565b82610adb816114b8565b610ae457600080fd5b60408051808201825284815260208082018581526000888152600983528490209251835551600190920191909155815185815290810184905285917f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e4691015b60405180910390a250505050565b82610b5b816114b8565b610b6457600080fd5b6000848152600260205260409020610b7d908484611f6c565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d75788484604051610b439291906126b2565b600080610bbe83603c6113cc565b90508051600003610bd25750600092915050565b610bdb81611ad0565b9392505050565b6060600a60008581526020019081526020016000208383604051610c07929190612679565b90815260200160405180910390208054610c20906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c906126dc565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505090509392505050565b6000818152600360205260409020805460609190610cc4906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf0906126dc565b8015610d3d5780601f10610d1257610100808354040283529160200191610d3d565b820191906000526020600020905b815481529060010190602001808311610d2057829003601f168201915b50505050509050919050565b83610d53816114b8565b610d5c57600080fd5b83610d68600182612662565b1615610d7357600080fd5b6000858152602081815260408083208784529091529020610d95908484611f6c565b50604051849086907faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe390600090a35050505050565b6000818152600860205260409020805460609190610cc4906126dc565b82610df1816114b8565b610dfa57600080fd5b6000848152600860205260409020610e13908484611f6c565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051610b439291906126b2565b82610e50816114b8565b610e5957600080fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af7528484604051610e8b9291906122a0565b60405180910390a2603c8303610ee257837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2610ec684611ad0565b6040516001600160a01b03909116815260200160405180910390a25b600084815260016020908152604080832086845282529091208351610f0992850190611ff0565b5050505050565b6001600160a01b0382163303610fac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c660000000000000000000000000000000000000000000000606482015260840160405180910390fd5b336000818152600b602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000838152600560209081526040808320600483528184205484528252808320858452825280832061ffff851684529091529020805460609190610c20906126dc565b60608167ffffffffffffffff81111561107657611076612364565b6040519080825280602002602001820160405280156110a957816020015b60608152602001906001900390816110945790505b50905060005b8281101561116f57600080308686858181106110cd576110cd6126c6565b90506020028101906110df9190612716565b6040516110ed929190612679565b600060405180830381855af49150503d8060008114611128576040519150601f19603f3d011682016040523d82523d6000602084013e61112d565b606091505b50915091508161113c57600080fd5b8084848151811061114f5761114f6126c6565b6020026020010181905250505080806111679061275d565b9150506110af565b5092915050565b80611180816114b8565b61118957600080fd5b60008281526004602052604081208054916111a38361275d565b909155505060405182907fb757169b8492ca2f1c6619d9d76ce22803035c3b1d5f6930dffe7b127c1a198390600090a25050565b6000818152600260205260409020805460609190610cc4906126dc565b826111fe816114b8565b61120757600080fd5b60008481526003602052604081208054611220906126dc565b80601f016020809104026020016040519081016040528092919081815260200182805461124c906126dc565b80156112995780601f1061126e57610100808354040283529160200191611299565b820191906000526020600020905b81548152906001019060200180831161127c57829003601f168201915b50505060008881526003602052604090209293506112bc92915086905085611f6c565b50847f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f858286866040516112f193929190612776565b60405180910390a25050505050565b8161130a816114b8565b61131357600080fd5b61132283603c61034285611af8565b505050565b82611331816114b8565b61133a57600080fd5b60008481526007602090815260408083206001600160e01b031987168085529083529281902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038716908117909155905190815286917f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa910160405180910390a350505050565b600082815260016020908152604080832084845290915290208054606091906113f4906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054611420906126dc565b801561146d5780601f106114425761010080835404028352916020019161146d565b820191906000526020600020905b81548152906001019060200180831161145057829003601f168201915b5050505050905092915050565b60006001600160e01b031982167f59d1d43c000000000000000000000000000000000000000000000000000000001480610483575061048382611b31565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806115195750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b1561152657506001919050565b6040517f02571be3000000000000000000000000000000000000000000000000000000008152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906302571be390602401602060405180830381865afa1580156115a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cb91906127a6565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316036116ab576040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906127a6565b90505b6001600160a01b038116331480610bdb57506001600160a01b0381166000908152600b6020908152604080832033845290915290205460ff16610bdb565b6117376040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c08101829052610483816119e8565b60208101518151606091610483916117629082611b6f565b84519190611bd1565b60a081015160c082015160609161048391611762908290612662565b600081518351148015610bdb5750610bdb8360008460008751611c48565b600087815260046020908152604082205488519189019190912090916117cc878787611bd1565b905083156118d55760008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461180c906126dc565b1590506118605760008a815260066020908152604080832086845282528083208584529091528120805461ffff1691611844836127c3565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c168452909152812061189691612064565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a6040516118c89291906127e1565b60405180910390a26119dc565b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461190d906126dc565b90506000036119635760008a815260066020908152604080832086845282528083208584529091528120805461ffff169161194783612807565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684528252909120825161199e92840190611ff0565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a846040516119d393929190612828565b60405180910390a25b50505050505050505050565b60c081015160208201819052815151116119ff5750565b6000611a1382600001518360200151611b6f565b8260200151611a229190612857565b8251909150611a319082611c6b565b61ffff166040830152611a45600282612857565b8251909150611a549082611c6b565b61ffff166060830152611a68600282612857565b8251909150611a779082611c93565b63ffffffff166080830152611a8d600482612857565b8251909150600090611a9f9083611c6b565b61ffff169050611ab0600283612857565b60a084018190529150611ac38183612857565b60c0909301929092525050565b60008151601414611ae057600080fd5b50602001516c01000000000000000000000000900490565b6040805160148082528183019092526060916020820181803683375050506c010000000000000000000000009290920260208301525090565b60006001600160e01b031982167fc8690233000000000000000000000000000000000000000000000000000000001480610483575061048382611cbd565b6000815b83518110611b8357611b8361286f565b6000611b8f8583611cfb565b60ff169050611b9f816001612857565b611ba99083612857565b915080600003611bb95750611bbf565b50611b73565b611bc98382612662565b949350505050565b8251606090611be08385612857565b1115611beb57600080fd5b60008267ffffffffffffffff811115611c0657611c06612364565b6040519080825280601f01601f191660200182016040528015611c30576020820181803683370190505b509050602080820190868601016109ab828287611d1f565b6000611c55848484611d75565b611c60878785611d75565b149695505050505050565b8151600090611c7b836002612857565b1115611c8657600080fd5b50016002015161ffff1690565b8151600090611ca3836004612857565b1115611cae57600080fd5b50016004015163ffffffff1690565b60006001600160e01b031982167f691f3431000000000000000000000000000000000000000000000000000000001480610483575061048382611d99565b6000828281518110611d0f57611d0f6126c6565b016020015160f81c905092915050565b60208110611d575781518352611d36602084612857565b9250611d43602083612857565b9150611d50602082612662565b9050611d1f565b905182516020929092036101000a6000190180199091169116179052565b8251600090611d848385612857565b1115611d8f57600080fd5b5091016020012090565b60006001600160e01b031982167f124a319c00000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167fa8fa5682000000000000000000000000000000000000000000000000000000001480611e3557506001600160e01b031982167f5c98042b00000000000000000000000000000000000000000000000000000000145b8061048357506104838260006001600160e01b031982167fbc1c58d100000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167f3b3b57de000000000000000000000000000000000000000000000000000000001480611edb57506001600160e01b031982167ff1cb7e0600000000000000000000000000000000000000000000000000000000145b8061048357506104838260006001600160e01b031982167f2203ab5600000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167fac9650d800000000000000000000000000000000000000000000000000000000148061048357506301ffc9a760e01b6001600160e01b0319831614610483565b828054611f78906126dc565b90600052602060002090601f016020900481019282611f9a5760008555611fe0565b82601f10611fb35782800160ff19823516178555611fe0565b82800160010185558215611fe0579182015b82811115611fe0578235825591602001919060010190611fc5565b50611fec9291506120a1565b5090565b828054611ffc906126dc565b90600052602060002090601f01602090048101928261201e5760008555611fe0565b82601f1061203757805160ff1916838001178555611fe0565b82800160010185558215611fe0579182015b82811115611fe0578251825591602001919060010190612049565b508054612070906126dc565b6000825580601f10612080575050565b601f01602090049060005260206000209081019061209e91906120a1565b50565b5b80821115611fec57600081556001016120a2565b80356001600160e01b0319811681146120ce57600080fd5b919050565b6000602082840312156120e557600080fd5b610bdb826120b6565b60008083601f84011261210057600080fd5b50813567ffffffffffffffff81111561211857600080fd5b602083019150836020828501011115610aca57600080fd5b60008060006040848603121561214557600080fd5b83359250602084013567ffffffffffffffff81111561216357600080fd5b61216f868287016120ee565b9497909650939450505050565b60008060008060006060868803121561219457600080fd5b85359450602086013567ffffffffffffffff808211156121b357600080fd5b6121bf89838a016120ee565b909650945060408801359150808211156121d857600080fd5b506121e5888289016120ee565b969995985093965092949392505050565b6000806040838503121561220957600080fd5b82359150612219602084016120b6565b90509250929050565b6000806040838503121561223557600080fd5b50508035926020909101359150565b60005b8381101561225f578181015183820152602001612247565b8381111561226e576000848401525b50505050565b6000815180845261228c816020860160208601612244565b601f01601f19169290920160200192915050565b828152604060208201526000611bc96040830184612274565b6000806000606084860312156122ce57600080fd5b505081359360208301359350604090920135919050565b6000602082840312156122f757600080fd5b5035919050565b602081526000610bdb6020830184612274565b6000806000806060858703121561232757600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561234c57600080fd5b612358878288016120ee565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561238f57600080fd5b8335925060208401359150604084013567ffffffffffffffff808211156123b557600080fd5b818601915086601f8301126123c957600080fd5b8135818111156123db576123db612364565b604051601f8201601f19908116603f0116810190838211818310171561240357612403612364565b8160405282815289602084870101111561241c57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6001600160a01b038116811461209e57600080fd5b6000806040838503121561246657600080fd5b82356124718161243e565b91506020830135801515811461248657600080fd5b809150509250929050565b6000806000606084860312156124a657600080fd5b8335925060208401359150604084013561ffff811681146124c657600080fd5b809150509250925092565b600080602083850312156124e457600080fd5b823567ffffffffffffffff808211156124fc57600080fd5b818501915085601f83011261251057600080fd5b81358181111561251f57600080fd5b8660208260051b850101111561253457600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561259b57603f19888603018452612589858351612274565b9450928501929085019060010161256d565b5092979650505050505050565b600080604083850312156125bb57600080fd5b8235915060208301356124868161243e565b6000806000606084860312156125e257600080fd5b833592506125f2602085016120b6565b915060408401356124c68161243e565b6000806040838503121561261557600080fd5b82356126208161243e565b915060208301356124868161243e565b60008251612642818460208701612244565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b6000828210156126745761267461264c565b500390565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611bc9602083018486612689565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806126f057607f821691505b60208210810361271057634e487b7160e01b600052602260045260246000fd5b50919050565b6000808335601e1984360301811261272d57600080fd5b83018035915067ffffffffffffffff82111561274857600080fd5b602001915036819003821315610aca57600080fd5b60006001820161276f5761276f61264c565b5060010190565b6040815260006127896040830186612274565b828103602084015261279c818587612689565b9695505050505050565b6000602082840312156127b857600080fd5b8151610bdb8161243e565b600061ffff8216806127d7576127d761264c565b6000190192915050565b6040815260006127f46040830185612274565b905061ffff831660208301529392505050565b600061ffff80831681810361281e5761281e61264c565b6001019392505050565b60608152600061283b6060830186612274565b61ffff85166020840152828103604084015261279c8185612274565b6000821982111561286a5761286a61264c565b500190565b634e487b7160e01b600052600160045260246000fdfea264697066735822122007b14afb2e09b18ad0599488e8ccb4c8d7ee1d7beea07ad1105dbf344d82f4de64736f6c634300080d0033000000000000000000000000d0c1411f038db980f6c268d3cc0ef8d32127ad52
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101ae5760003560e01c806377372213116100ee578063bc1c58d111610097578063d5fa2b0011610071578063d5fa2b0014610403578063e59d895d14610416578063e985e9c514610429578063f1cb7e061461046557600080fd5b8063bc1c58d1146103a0578063c8690233146103b3578063ce3decdc146103f057600080fd5b8063a8fa5682116100c8578063a8fa56821461035a578063ac9650d81461036d578063ad5780af1461038d57600080fd5b806377372213146103215780638b95dd7114610334578063a22cb4651461034757600080fd5b8063304e6ade1161015b57806359d1d43c1161013557806359d1d43c146102c85780635c98042b146102e8578063623195b0146102fb578063691f34311461030e57600080fd5b8063304e6ade146102625780633b3b57de146102755780634cbf6ba41461028857600080fd5b8063124a319c1161018c578063124a319c146102035780632203ab561461022e57806329cd62ea1461024f57600080fd5b806301ffc9a7146101b35780630af179d7146101db57806310f13a8c146101f0575b600080fd5b6101c66101c13660046120d3565b610478565b60405190151581526020015b60405180910390f35b6101ee6101e9366004612130565b610489565b005b6101ee6101fe36600461217c565b610677565b6102166102113660046121f6565b610724565b6040516001600160a01b0390911681526020016101d2565b61024161023c366004612222565b6109b6565b6040516101d29291906122a0565b6101ee61025d3660046122b9565b610ad1565b6101ee610270366004612130565b610b51565b6102166102833660046122e5565b610bb0565b6101c6610296366004612222565b600091825260066020908152604080842060048352818520548552825280842092845291905290205461ffff16151590565b6102db6102d6366004612130565b610be2565b6040516101d291906122fe565b6102db6102f63660046122e5565b610ca7565b6101ee610309366004612311565b610d49565b6102db61031c3660046122e5565b610dca565b6101ee61032f366004612130565b610de7565b6101ee61034236600461237a565b610e46565b6101ee610355366004612453565b610f10565b6102db610368366004612491565b611018565b61038061037b3660046124d1565b61105b565b6040516101d29190612546565b6101ee61039b3660046122e5565b611176565b6102db6103ae3660046122e5565b6111d7565b6103db6103c13660046122e5565b600090815260096020526040902080546001909101549091565b604080519283526020830191909152016101d2565b6101ee6103fe366004612130565b6111f4565b6101ee6104113660046125a8565b611300565b6101ee6104243660046125cd565b611327565b6101c6610437366004612602565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205460ff1690565b6102db610473366004612222565b6113cc565b60006104838261147a565b92915050565b82610493816114b8565b61049c57600080fd5b6000806060806000806104e960008a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506116e99050565b90505b80515160208201511015610612578561ffff1660000361055157806040015195506105168161174a565b9350836040516020016105299190612630565b60405160208183030381529060405280519060200120915061054a8161176b565b9250610604565b600061055c8261174a565b9050816040015161ffff168761ffff16141580610580575061057e8582611787565b155b15610602576105db8b86898d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505060208801518c91506105d3908290612662565b8a51156117a5565b8160400151965081602001519550809450848051906020012092506105ff8261176b565b93505b505b61060d816119e8565b6104ec565b5082511561066c5761066c8984878b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061066491508290508e612662565b8851156117a5565b505050505050505050565b84610681816114b8565b61068a57600080fd5b8282600a600089815260200190815260200160002087876040516106af929190612679565b9081526040519081900360200190206106c9929091611f6c565b5084846040516106da929190612679565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a755087876040516107149291906126b2565b60405180910390a3505050505050565b60008281526007602090815260408083206001600160e01b0319851684529091528120546001600160a01b0316801561075e579050610483565b600061076985610bb0565b90506001600160a01b03811661078457600092505050610483565b6040516301ffc9a760e01b602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b179052516107f19190612630565b600060405180830381855afa9150503d806000811461082c576040519150601f19603f3d011682016040523d82523d6000602084013e610831565b606091505b5091509150811580610844575060208151105b80610886575080601f8151811061085d5761085d6126c6565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016155b15610898576000945050505050610483565b6040516001600160e01b0319871660248201526001600160a01b0384169060440160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166301ffc9a760e01b179052516109039190612630565b600060405180830381855afa9150503d806000811461093e576040519150601f19603f3d011682016040523d82523d6000602084013e610943565b606091505b509092509050811580610957575060208151105b80610999575080601f81518110610970576109706126c6565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016155b156109ab576000945050505050610483565b509095945050505050565b600082815260208190526040812060609060015b848111610ab157808516158015906109fa5750600081815260208390526040812080546109f6906126dc565b9050115b15610aa95780826000838152602001908152602001600020808054610a1e906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610a4a906126dc565b8015610a975780601f10610a6c57610100808354040283529160200191610a97565b820191906000526020600020905b815481529060010190602001808311610a7a57829003601f168201915b50505050509050935093505050610aca565b60011b6109ca565b5060006040518060200160405280600081525092509250505b9250929050565b82610adb816114b8565b610ae457600080fd5b60408051808201825284815260208082018581526000888152600983528490209251835551600190920191909155815185815290810184905285917f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e4691015b60405180910390a250505050565b82610b5b816114b8565b610b6457600080fd5b6000848152600260205260409020610b7d908484611f6c565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d75788484604051610b439291906126b2565b600080610bbe83603c6113cc565b90508051600003610bd25750600092915050565b610bdb81611ad0565b9392505050565b6060600a60008581526020019081526020016000208383604051610c07929190612679565b90815260200160405180910390208054610c20906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610c4c906126dc565b8015610c995780601f10610c6e57610100808354040283529160200191610c99565b820191906000526020600020905b815481529060010190602001808311610c7c57829003601f168201915b505050505090509392505050565b6000818152600360205260409020805460609190610cc4906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054610cf0906126dc565b8015610d3d5780601f10610d1257610100808354040283529160200191610d3d565b820191906000526020600020905b815481529060010190602001808311610d2057829003601f168201915b50505050509050919050565b83610d53816114b8565b610d5c57600080fd5b83610d68600182612662565b1615610d7357600080fd5b6000858152602081815260408083208784529091529020610d95908484611f6c565b50604051849086907faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe390600090a35050505050565b6000818152600860205260409020805460609190610cc4906126dc565b82610df1816114b8565b610dfa57600080fd5b6000848152600860205260409020610e13908484611f6c565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051610b439291906126b2565b82610e50816114b8565b610e5957600080fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af7528484604051610e8b9291906122a0565b60405180910390a2603c8303610ee257837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2610ec684611ad0565b6040516001600160a01b03909116815260200160405180910390a25b600084815260016020908152604080832086845282529091208351610f0992850190611ff0565b5050505050565b6001600160a01b0382163303610fac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c660000000000000000000000000000000000000000000000606482015260840160405180910390fd5b336000818152600b602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000838152600560209081526040808320600483528184205484528252808320858452825280832061ffff851684529091529020805460609190610c20906126dc565b60608167ffffffffffffffff81111561107657611076612364565b6040519080825280602002602001820160405280156110a957816020015b60608152602001906001900390816110945790505b50905060005b8281101561116f57600080308686858181106110cd576110cd6126c6565b90506020028101906110df9190612716565b6040516110ed929190612679565b600060405180830381855af49150503d8060008114611128576040519150601f19603f3d011682016040523d82523d6000602084013e61112d565b606091505b50915091508161113c57600080fd5b8084848151811061114f5761114f6126c6565b6020026020010181905250505080806111679061275d565b9150506110af565b5092915050565b80611180816114b8565b61118957600080fd5b60008281526004602052604081208054916111a38361275d565b909155505060405182907fb757169b8492ca2f1c6619d9d76ce22803035c3b1d5f6930dffe7b127c1a198390600090a25050565b6000818152600260205260409020805460609190610cc4906126dc565b826111fe816114b8565b61120757600080fd5b60008481526003602052604081208054611220906126dc565b80601f016020809104026020016040519081016040528092919081815260200182805461124c906126dc565b80156112995780601f1061126e57610100808354040283529160200191611299565b820191906000526020600020905b81548152906001019060200180831161127c57829003601f168201915b50505060008881526003602052604090209293506112bc92915086905085611f6c565b50847f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f858286866040516112f193929190612776565b60405180910390a25050505050565b8161130a816114b8565b61131357600080fd5b61132283603c61034285611af8565b505050565b82611331816114b8565b61133a57600080fd5b60008481526007602090815260408083206001600160e01b031987168085529083529281902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038716908117909155905190815286917f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa910160405180910390a350505050565b600082815260016020908152604080832084845290915290208054606091906113f4906126dc565b80601f0160208091040260200160405190810160405280929190818152602001828054611420906126dc565b801561146d5780601f106114425761010080835404028352916020019161146d565b820191906000526020600020905b81548152906001019060200180831161145057829003601f168201915b5050505050905092915050565b60006001600160e01b031982167f59d1d43c000000000000000000000000000000000000000000000000000000001480610483575061048382611b31565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614806115195750336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016145b1561152657506001919050565b6040517f02571be3000000000000000000000000000000000000000000000000000000008152600481018390526000907f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e6001600160a01b0316906302571be390602401602060405180830381865afa1580156115a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115cb91906127a6565b90507f000000000000000000000000d0c1411f038db980f6c268d3cc0ef8d32127ad526001600160a01b0316816001600160a01b0316036116ab576040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018490527f000000000000000000000000d0c1411f038db980f6c268d3cc0ef8d32127ad526001600160a01b031690636352211e90602401602060405180830381865afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906127a6565b90505b6001600160a01b038116331480610bdb57506001600160a01b0381166000908152600b6020908152604080832033845290915290205460ff16610bdb565b6117376040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c08101829052610483816119e8565b60208101518151606091610483916117629082611b6f565b84519190611bd1565b60a081015160c082015160609161048391611762908290612662565b600081518351148015610bdb5750610bdb8360008460008751611c48565b600087815260046020908152604082205488519189019190912090916117cc878787611bd1565b905083156118d55760008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461180c906126dc565b1590506118605760008a815260066020908152604080832086845282528083208584529091528120805461ffff1691611844836127c3565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c168452909152812061189691612064565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a6040516118c89291906127e1565b60405180910390a26119dc565b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461190d906126dc565b90506000036119635760008a815260066020908152604080832086845282528083208584529091528120805461ffff169161194783612807565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526005602090815260408083208684528252808320858452825280832061ffff8c1684528252909120825161199e92840190611ff0565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a846040516119d393929190612828565b60405180910390a25b50505050505050505050565b60c081015160208201819052815151116119ff5750565b6000611a1382600001518360200151611b6f565b8260200151611a229190612857565b8251909150611a319082611c6b565b61ffff166040830152611a45600282612857565b8251909150611a549082611c6b565b61ffff166060830152611a68600282612857565b8251909150611a779082611c93565b63ffffffff166080830152611a8d600482612857565b8251909150600090611a9f9083611c6b565b61ffff169050611ab0600283612857565b60a084018190529150611ac38183612857565b60c0909301929092525050565b60008151601414611ae057600080fd5b50602001516c01000000000000000000000000900490565b6040805160148082528183019092526060916020820181803683375050506c010000000000000000000000009290920260208301525090565b60006001600160e01b031982167fc8690233000000000000000000000000000000000000000000000000000000001480610483575061048382611cbd565b6000815b83518110611b8357611b8361286f565b6000611b8f8583611cfb565b60ff169050611b9f816001612857565b611ba99083612857565b915080600003611bb95750611bbf565b50611b73565b611bc98382612662565b949350505050565b8251606090611be08385612857565b1115611beb57600080fd5b60008267ffffffffffffffff811115611c0657611c06612364565b6040519080825280601f01601f191660200182016040528015611c30576020820181803683370190505b509050602080820190868601016109ab828287611d1f565b6000611c55848484611d75565b611c60878785611d75565b149695505050505050565b8151600090611c7b836002612857565b1115611c8657600080fd5b50016002015161ffff1690565b8151600090611ca3836004612857565b1115611cae57600080fd5b50016004015163ffffffff1690565b60006001600160e01b031982167f691f3431000000000000000000000000000000000000000000000000000000001480610483575061048382611d99565b6000828281518110611d0f57611d0f6126c6565b016020015160f81c905092915050565b60208110611d575781518352611d36602084612857565b9250611d43602083612857565b9150611d50602082612662565b9050611d1f565b905182516020929092036101000a6000190180199091169116179052565b8251600090611d848385612857565b1115611d8f57600080fd5b5091016020012090565b60006001600160e01b031982167f124a319c00000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167fa8fa5682000000000000000000000000000000000000000000000000000000001480611e3557506001600160e01b031982167f5c98042b00000000000000000000000000000000000000000000000000000000145b8061048357506104838260006001600160e01b031982167fbc1c58d100000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167f3b3b57de000000000000000000000000000000000000000000000000000000001480611edb57506001600160e01b031982167ff1cb7e0600000000000000000000000000000000000000000000000000000000145b8061048357506104838260006001600160e01b031982167f2203ab5600000000000000000000000000000000000000000000000000000000148061048357506104838260006001600160e01b031982167fac9650d800000000000000000000000000000000000000000000000000000000148061048357506301ffc9a760e01b6001600160e01b0319831614610483565b828054611f78906126dc565b90600052602060002090601f016020900481019282611f9a5760008555611fe0565b82601f10611fb35782800160ff19823516178555611fe0565b82800160010185558215611fe0579182015b82811115611fe0578235825591602001919060010190611fc5565b50611fec9291506120a1565b5090565b828054611ffc906126dc565b90600052602060002090601f01602090048101928261201e5760008555611fe0565b82601f1061203757805160ff1916838001178555611fe0565b82800160010185558215611fe0579182015b82811115611fe0578251825591602001919060010190612049565b508054612070906126dc565b6000825580601f10612080575050565b601f01602090049060005260206000209081019061209e91906120a1565b50565b5b80821115611fec57600081556001016120a2565b80356001600160e01b0319811681146120ce57600080fd5b919050565b6000602082840312156120e557600080fd5b610bdb826120b6565b60008083601f84011261210057600080fd5b50813567ffffffffffffffff81111561211857600080fd5b602083019150836020828501011115610aca57600080fd5b60008060006040848603121561214557600080fd5b83359250602084013567ffffffffffffffff81111561216357600080fd5b61216f868287016120ee565b9497909650939450505050565b60008060008060006060868803121561219457600080fd5b85359450602086013567ffffffffffffffff808211156121b357600080fd5b6121bf89838a016120ee565b909650945060408801359150808211156121d857600080fd5b506121e5888289016120ee565b969995985093965092949392505050565b6000806040838503121561220957600080fd5b82359150612219602084016120b6565b90509250929050565b6000806040838503121561223557600080fd5b50508035926020909101359150565b60005b8381101561225f578181015183820152602001612247565b8381111561226e576000848401525b50505050565b6000815180845261228c816020860160208601612244565b601f01601f19169290920160200192915050565b828152604060208201526000611bc96040830184612274565b6000806000606084860312156122ce57600080fd5b505081359360208301359350604090920135919050565b6000602082840312156122f757600080fd5b5035919050565b602081526000610bdb6020830184612274565b6000806000806060858703121561232757600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561234c57600080fd5b612358878288016120ee565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561238f57600080fd5b8335925060208401359150604084013567ffffffffffffffff808211156123b557600080fd5b818601915086601f8301126123c957600080fd5b8135818111156123db576123db612364565b604051601f8201601f19908116603f0116810190838211818310171561240357612403612364565b8160405282815289602084870101111561241c57600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6001600160a01b038116811461209e57600080fd5b6000806040838503121561246657600080fd5b82356124718161243e565b91506020830135801515811461248657600080fd5b809150509250929050565b6000806000606084860312156124a657600080fd5b8335925060208401359150604084013561ffff811681146124c657600080fd5b809150509250925092565b600080602083850312156124e457600080fd5b823567ffffffffffffffff808211156124fc57600080fd5b818501915085601f83011261251057600080fd5b81358181111561251f57600080fd5b8660208260051b850101111561253457600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561259b57603f19888603018452612589858351612274565b9450928501929085019060010161256d565b5092979650505050505050565b600080604083850312156125bb57600080fd5b8235915060208301356124868161243e565b6000806000606084860312156125e257600080fd5b833592506125f2602085016120b6565b915060408401356124c68161243e565b6000806040838503121561261557600080fd5b82356126208161243e565b915060208301356124868161243e565b60008251612642818460208701612244565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b6000828210156126745761267461264c565b500390565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611bc9602083018486612689565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806126f057607f821691505b60208210810361271057634e487b7160e01b600052602260045260246000fd5b50919050565b6000808335601e1984360301811261272d57600080fd5b83018035915067ffffffffffffffff82111561274857600080fd5b602001915036819003821315610aca57600080fd5b60006001820161276f5761276f61264c565b5060010190565b6040815260006127896040830186612274565b828103602084015261279c818587612689565b9695505050505050565b6000602082840312156127b857600080fd5b8151610bdb8161243e565b600061ffff8216806127d7576127d761264c565b6000190192915050565b6040815260006127f46040830185612274565b905061ffff831660208301529392505050565b600061ffff80831681810361281e5761281e61264c565b6001019392505050565b60608152600061283b6060830186612274565b61ffff85166020840152828103604084015261279c8185612274565b6000821982111561286a5761286a61264c565b500190565b634e487b7160e01b600052600160045260246000fdfea264697066735822122007b14afb2e09b18ad0599488e8ccb4c8d7ee1d7beea07ad1105dbf344d82f4de64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d0c1411f038db980f6c268d3cc0ef8d32127ad52
-----Decoded View---------------
Arg [0] : wrapper (address): 0xD0C1411F038Db980f6C268D3Cc0ef8D32127ad52
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d0c1411f038db980f6c268d3cc0ef8d32127ad52
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.