diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9c7538b1..3bfc895d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,10 +2,25 @@ name: CI on: push: - branches: [master] + branches: [staging, mainnet] pull_request: jobs: + wiki_address_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js 16 + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: 'yarn' + + - run: yarn install --frozen-lockfile + + - name: Run wikiCheck + run: yarn wikiCheck test: runs-on: ubuntu-latest steps: diff --git a/contracts/dnssec-oracle/RRUtils.sol b/contracts/dnssec-oracle/RRUtils.sol index 6f356ecc..89a88b98 100644 --- a/contracts/dnssec-oracle/RRUtils.sol +++ b/contracts/dnssec-oracle/RRUtils.sol @@ -1,3 +1,4 @@ +//SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "../utils/BytesUtils.sol"; diff --git a/contracts/ethregistrar/ETHRegistrarController.sol b/contracts/ethregistrar/ETHRegistrarController.sol index fa144fa7..43a1bed6 100644 --- a/contracts/ethregistrar/ETHRegistrarController.sol +++ b/contracts/ethregistrar/ETHRegistrarController.sol @@ -20,7 +20,6 @@ error CommitmentTooOld(bytes32 commitment); error NameNotAvailable(string name); error DurationTooShort(uint256 duration); error ResolverRequiredWhenDataSupplied(); -error ResolverRequiredWhenReverseRecord(); error UnexpiredCommitmentExists(bytes32 commitment); error InsufficientValue(); error Unauthorised(bytes32 node); @@ -121,9 +120,6 @@ contract ETHRegistrarController is uint16 ownerControlledFuses ) public pure override returns (bytes32) { bytes32 label = keccak256(bytes(name)); - if (resolver == address(0) && reverseRecord == true) { - revert ResolverRequiredWhenReverseRecord(); - } if (data.length > 0 && resolver == address(0)) { revert ResolverRequiredWhenDataSupplied(); } diff --git a/contracts/registry/ENS.sol b/contracts/registry/ENS.sol index d35f68e4..6b5a21dc 100644 --- a/contracts/registry/ENS.sol +++ b/contracts/registry/ENS.sol @@ -1,3 +1,4 @@ +//SPDX-License-Identifier: MIT pragma solidity >=0.8.4; interface ENS { diff --git a/contracts/resolvers/OwnedResolver.sol b/contracts/resolvers/OwnedResolver.sol index 5a6b581e..429f3b53 100644 --- a/contracts/resolvers/OwnedResolver.sol +++ b/contracts/resolvers/OwnedResolver.sol @@ -1,3 +1,4 @@ +//SPDX-License-Identifier: MIT pragma solidity >=0.8.4; import "@openzeppelin/contracts/access/Ownable.sol"; import "./profiles/ABIResolver.sol"; diff --git a/contracts/utils/BytesUtils.sol b/contracts/utils/BytesUtils.sol index b1a13ca3..0f8fd7c2 100644 --- a/contracts/utils/BytesUtils.sol +++ b/contracts/utils/BytesUtils.sol @@ -1,3 +1,4 @@ +//SPDX-License-Identifier: MIT pragma solidity ^0.8.4; library BytesUtils { diff --git a/contracts/utils/UniversalResolver.sol b/contracts/utils/UniversalResolver.sol index 575e11f0..79f9922a 100644 --- a/contracts/utils/UniversalResolver.sol +++ b/contracts/utils/UniversalResolver.sol @@ -320,9 +320,7 @@ contract UniversalResolver is ERC165, Ownable { Result memory result = results[0]; - if (!result.success) { - revert ResolverError(result.returnData); - } + _checkResolveSingle(result); if (metaData.length > 0) { (string memory resolvedName, address reverseResolverAddress) = abi @@ -658,7 +656,7 @@ contract UniversalResolver is ERC165, Ownable { returnData = abi.decode(returnData, (bytes)); } results[i] = Result(success, returnData); - extraDatas[i].data = multicallData.data[i]; + extraDatas[i].data = item; } if (offchainCount == 0) { diff --git a/deploy/utils/00_deploy_universal_resolver.ts b/deploy/utils/00_deploy_universal_resolver.ts index bad19245..0df6ecd2 100644 --- a/deploy/utils/00_deploy_universal_resolver.ts +++ b/deploy/utils/00_deploy_universal_resolver.ts @@ -20,10 +20,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { log: true, }) - const UR = await ethers.getContract('UniversalResolver') - const tx = await UR.transferOwnership(owner) - console.log(`Transfer ownership to ${owner} (tx: ${tx.hash})...`) - await tx.wait() + if (owner !== undefined && owner !== deployer) { + const UR = await ethers.getContract('UniversalResolver') + const tx = await UR.transferOwnership(owner) + console.log(`Transfer ownership to ${owner} (tx: ${tx.hash})...`) + await tx.wait() + } } func.id = 'universal-resolver' diff --git a/deployments/goerli/UniversalResolver.json b/deployments/goerli/UniversalResolver.json index 575bb5e5..6de924aa 100644 --- a/deployments/goerli/UniversalResolver.json +++ b/deployments/goerli/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", + "address": "0x898A1182F3C2BBBF0b16b4DfEf63E9c3e9eB4821", "abi": [ { "inputs": [ @@ -596,48 +596,48 @@ "type": "function" } ], - "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", + "transactionHash": "0x7121a4e2c2f0412faf701c2cb3d8ee8eebf771148eb06f205a011b3d155d24d0", "receipt": { "to": null, "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", - "contractAddress": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", - "transactionIndex": 56, - "gasUsed": "3157648", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000000", - "blockHash": "0xa931bd30b0b1a98460ecf13105220e297bf19dc4836a14dba8bc6630e86a7c5b", - "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", + "contractAddress": "0x898A1182F3C2BBBF0b16b4DfEf63E9c3e9eB4821", + "transactionIndex": 36, + "gasUsed": "3139326", + "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000020000000000000000000008000000100000000000000000000000000000000000000", + "blockHash": "0x2a75b2f5921d015c0b05338a0f9d934063dd4f18fe6488b83970303073659c2b", + "transactionHash": "0x7121a4e2c2f0412faf701c2cb3d8ee8eebf771148eb06f205a011b3d155d24d0", "logs": [ { - "transactionIndex": 56, - "blockNumber": 10339206, - "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", - "address": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", + "transactionIndex": 36, + "blockNumber": 10559621, + "transactionHash": "0x7121a4e2c2f0412faf701c2cb3d8ee8eebf771148eb06f205a011b3d155d24d0", + "address": "0x898A1182F3C2BBBF0b16b4DfEf63E9c3e9eB4821", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], "data": "0x", - "logIndex": 77, - "blockHash": "0xa931bd30b0b1a98460ecf13105220e297bf19dc4836a14dba8bc6630e86a7c5b" + "logIndex": 172, + "blockHash": "0x2a75b2f5921d015c0b05338a0f9d934063dd4f18fe6488b83970303073659c2b" } ], - "blockNumber": 10339206, - "cumulativeGasUsed": "9266049", + "blockNumber": 10559621, + "cumulativeGasUsed": "13595024", "status": 1, "byzantium": true }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", [ - "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" + "https://ccip-v2.ens.xyz" ] ], - "numDeployments": 7, - "solcInputHash": "b8a92c9207ae2a5ea22df4d7303f97f4", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0xcae20ad72181f47dfe7fba7d88e8d902a01576b16e93362878e726989d6cfb4d\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n if (!result.success) {\\n revert ResolverError(result.returnData);\\n }\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = multicallData.data[i];\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0ba4e0ec4c2823f16c5d01402a605999a52a874311568025ba752d2d4db6af1d\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003a9138038062003a918339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516135d2620004bf600039600081816101ea015261150601526135d26000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", + "numDeployments": 8, + "solcInputHash": "49f758ec505ff69b72f3179ac11d7cfc", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n uint256 hexLength = lastIdx - idx;\\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\\n revert(\\\"Invalid string length\\\");\\n }\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0x4a8a9c72d6f3effb80b310faa6dc273e7adbc3b949df9c7a42e290e5b13519f3\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = item;\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2a03a3a94a411b599690e58634c2c5695561cbe4a16fae60cbfefa872a6c2f7b\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003b0f38038062003b0f8339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613650620004bf600039600081816101ea01526114fc01526136506000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -703,7 +703,7 @@ "type": "t_address" }, { - "astId": 1511, + "astId": 1537, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "batchGatewayURLs", "offset": 0, diff --git a/deployments/goerli/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json b/deployments/goerli/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json new file mode 100644 index 00000000..51bd8239 --- /dev/null +++ b/deployments/goerli/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json @@ -0,0 +1,101 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/registry/ENS.sol": { + "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n // Logged when the owner of a node assigns a new owner to a subnode.\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n // Logged when the owner of a node transfers ownership to a new account.\n event Transfer(bytes32 indexed node, address owner);\n\n // Logged when the resolver for a node changes.\n event NewResolver(bytes32 indexed node, address resolver);\n\n // Logged when the TTL of a node changes\n event NewTTL(bytes32 indexed node, uint64 ttl);\n\n // Logged when an operator is added or removed.\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n function setRecord(\n bytes32 node,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner\n ) external returns (bytes32);\n\n function setResolver(bytes32 node, address resolver) external;\n\n function setOwner(bytes32 node, address owner) external;\n\n function setTTL(bytes32 node, uint64 ttl) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function owner(bytes32 node) external view returns (address);\n\n function resolver(bytes32 node) external view returns (address);\n\n function ttl(bytes32 node) external view returns (uint64);\n\n function recordExists(bytes32 node) external view returns (bool);\n\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/resolvers/profiles/IABIResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IABIResolver {\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\n\n /**\n * Returns the ABI associated with an ENS node.\n * Defined in EIP205.\n * @param node The ENS node to query\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\n * @return contentType The content type of the return value\n * @return data The ABI data\n */\n function ABI(\n bytes32 node,\n uint256 contentTypes\n ) external view returns (uint256, bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddressResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the new (multicoin) addr function.\n */\ninterface IAddressResolver {\n event AddressChanged(\n bytes32 indexed node,\n uint256 coinType,\n bytes newAddress\n );\n\n function addr(\n bytes32 node,\n uint256 coinType\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddrResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the legacy (ETH-only) addr function.\n */\ninterface IAddrResolver {\n event AddrChanged(bytes32 indexed node, address a);\n\n /**\n * Returns the address associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated address.\n */\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "contracts/resolvers/profiles/IContentHashResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IContentHashResolver {\n event ContenthashChanged(bytes32 indexed node, bytes hash);\n\n /**\n * Returns the contenthash associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function contenthash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSRecordResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSRecordResolver {\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\n event DNSRecordChanged(\n bytes32 indexed node,\n bytes name,\n uint16 resource,\n bytes record\n );\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\n\n /**\n * Obtain a DNS record.\n * @param node the namehash of the node for which to fetch the record\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\n * @return the DNS record in wire format if present, otherwise empty\n */\n function dnsRecord(\n bytes32 node,\n bytes32 name,\n uint16 resource\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSZoneResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSZoneResolver {\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\n event DNSZonehashChanged(\n bytes32 indexed node,\n bytes lastzonehash,\n bytes zonehash\n );\n\n /**\n * zonehash obtains the hash for the zone.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function zonehash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IExtendedResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n function resolve(\n bytes memory name,\n bytes memory data\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IInterfaceResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IInterfaceResolver {\n event InterfaceChanged(\n bytes32 indexed node,\n bytes4 indexed interfaceID,\n address implementer\n );\n\n /**\n * Returns the address of a contract that implements the specified interface for this name.\n * If an implementer has not been set for this interfaceID and name, the resolver will query\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\n * will be returned.\n * @param node The ENS node to query.\n * @param interfaceID The EIP 165 interface ID to check for.\n * @return The address that implements this interface, or 0 if the interface is unsupported.\n */\n function interfaceImplementer(\n bytes32 node,\n bytes4 interfaceID\n ) external view returns (address);\n}\n" + }, + "contracts/resolvers/profiles/INameResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface INameResolver {\n event NameChanged(bytes32 indexed node, string name);\n\n /**\n * Returns the name associated with an ENS node, for reverse records.\n * Defined in EIP181.\n * @param node The ENS node to query.\n * @return The associated name.\n */\n function name(bytes32 node) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/profiles/IPubkeyResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IPubkeyResolver {\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\n\n /**\n * Returns the SECP256k1 public key associated with an ENS node.\n * Defined in EIP 619.\n * @param node The ENS node to query\n * @return x The X coordinate of the curve point for the public key.\n * @return y The Y coordinate of the curve point for the public key.\n */\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\n}\n" + }, + "contracts/resolvers/profiles/ITextResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface ITextResolver {\n event TextChanged(\n bytes32 indexed node,\n string indexed indexedKey,\n string key,\n string value\n );\n\n /**\n * Returns the text data associated with an ENS node and key.\n * @param node The ENS node to query.\n * @param key The text data key to query.\n * @return The associated text data.\n */\n function text(\n bytes32 node,\n string calldata key\n ) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/Resolver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./profiles/IABIResolver.sol\";\nimport \"./profiles/IAddressResolver.sol\";\nimport \"./profiles/IAddrResolver.sol\";\nimport \"./profiles/IContentHashResolver.sol\";\nimport \"./profiles/IDNSRecordResolver.sol\";\nimport \"./profiles/IDNSZoneResolver.sol\";\nimport \"./profiles/IInterfaceResolver.sol\";\nimport \"./profiles/INameResolver.sol\";\nimport \"./profiles/IPubkeyResolver.sol\";\nimport \"./profiles/ITextResolver.sol\";\nimport \"./profiles/IExtendedResolver.sol\";\n\n/**\n * A generic resolver interface which includes all the functions including the ones deprecated\n */\ninterface Resolver is\n IERC165,\n IABIResolver,\n IAddressResolver,\n IAddrResolver,\n IContentHashResolver,\n IDNSRecordResolver,\n IDNSZoneResolver,\n IInterfaceResolver,\n INameResolver,\n IPubkeyResolver,\n ITextResolver,\n IExtendedResolver\n{\n /* Deprecated events */\n event ContentChanged(bytes32 indexed node, bytes32 hash);\n\n function setApprovalForAll(address, bool) external;\n\n function approve(bytes32 node, address delegate, bool approved) external;\n\n function isApprovedForAll(address account, address operator) external;\n\n function isApprovedFor(\n address owner,\n bytes32 node,\n address delegate\n ) external;\n\n function setABI(\n bytes32 node,\n uint256 contentType,\n bytes calldata data\n ) external;\n\n function setAddr(bytes32 node, address addr) external;\n\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\n\n function setContenthash(bytes32 node, bytes calldata hash) external;\n\n function setDnsrr(bytes32 node, bytes calldata data) external;\n\n function setName(bytes32 node, string calldata _name) external;\n\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\n\n function setText(\n bytes32 node,\n string calldata key,\n string calldata value\n ) external;\n\n function setInterface(\n bytes32 node,\n bytes4 interfaceID,\n address implementer\n ) external;\n\n function multicall(\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n function multicallWithNodeCheck(\n bytes32 nodehash,\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n /* Deprecated functions */\n function content(bytes32 node) external view returns (bytes32);\n\n function multihash(bytes32 node) external view returns (bytes memory);\n\n function setContent(bytes32 node, bytes32 hash) external;\n\n function setMultihash(bytes32 node, bytes calldata hash) external;\n}\n" + }, + "contracts/utils/HexUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nlibrary HexUtils {\n /**\n * @dev Attempts to parse bytes32 from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexStringToBytes32(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (bytes32 r, bool valid) {\n uint256 hexLength = lastIdx - idx;\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\n revert(\"Invalid string length\");\n }\n valid = true;\n assembly {\n // check that the index to read to is not past the end of the string\n if gt(lastIdx, mload(str)) {\n revert(0, 0)\n }\n\n function getHex(c) -> ascii {\n // chars 48-57: 0-9\n if and(gt(c, 47), lt(c, 58)) {\n ascii := sub(c, 48)\n leave\n }\n // chars 65-70: A-F\n if and(gt(c, 64), lt(c, 71)) {\n ascii := add(sub(c, 65), 10)\n leave\n }\n // chars 97-102: a-f\n if and(gt(c, 96), lt(c, 103)) {\n ascii := add(sub(c, 97), 10)\n leave\n }\n // invalid char\n ascii := 0xff\n }\n\n let ptr := add(str, 32)\n for {\n let i := idx\n } lt(i, lastIdx) {\n i := add(i, 2)\n } {\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\n // if either byte is invalid, set invalid and break loop\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\n valid := false\n break\n }\n let combined := or(shl(4, byte1), byte2)\n r := or(shl(8, r), combined)\n }\n }\n }\n\n /**\n * @dev Attempts to parse an address from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexToAddress(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (address, bool) {\n if (lastIdx - idx < 40) return (address(0x0), false);\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\n return (address(uint160(uint256(r))), valid);\n }\n}\n" + }, + "contracts/utils/LowLevelCallUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nlibrary LowLevelCallUtils {\n using Address for address;\n\n /**\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data\n ) internal view returns (bool success) {\n return functionStaticCall(target, data, gasleft());\n }\n\n /**\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @param gasLimit The gas limit to use for the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n uint256 gasLimit\n ) internal view returns (bool success) {\n require(\n target.isContract(),\n \"LowLevelCallUtils: static call to non-contract\"\n );\n assembly {\n success := staticcall(\n gasLimit,\n target,\n add(data, 32),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n /**\n * @dev Returns the size of the return data of the most recent external call.\n */\n function returnDataSize() internal pure returns (uint256 len) {\n assembly {\n len := returndatasize()\n }\n }\n\n /**\n * @dev Reads return data from the most recent external call.\n * @param offset Offset into the return data.\n * @param length Number of bytes to return.\n */\n function readReturnData(\n uint256 offset,\n uint256 length\n ) internal pure returns (bytes memory data) {\n data = new bytes(length);\n assembly {\n returndatacopy(add(data, 32), offset, length)\n }\n }\n\n /**\n * @dev Reverts with the return data from the most recent external call.\n */\n function propagateRevert() internal pure {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n}\n" + }, + "contracts/utils/NameEncoder.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\n\nlibrary NameEncoder {\n using BytesUtils for bytes;\n\n function dnsEncodeName(\n string memory name\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\n uint8 labelLength = 0;\n bytes memory bytesName = bytes(name);\n uint256 length = bytesName.length;\n dnsName = new bytes(length + 2);\n node = 0;\n if (length == 0) {\n dnsName[0] = 0;\n return (dnsName, node);\n }\n\n // use unchecked to save gas since we check for an underflow\n // and we check for the length before the loop\n unchecked {\n for (uint256 i = length - 1; i >= 0; i--) {\n if (bytesName[i] == \".\") {\n dnsName[i + 1] = bytes1(labelLength);\n node = keccak256(\n abi.encodePacked(\n node,\n bytesName.keccak(i + 1, labelLength)\n )\n );\n labelLength = 0;\n } else {\n labelLength += 1;\n dnsName[i + 1] = bytesName[i];\n }\n if (i == 0) {\n break;\n }\n }\n }\n\n node = keccak256(\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\n );\n\n dnsName[0] = bytes1(labelLength);\n return (dnsName, node);\n }\n}\n" + }, + "contracts/utils/UniversalResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17 <0.9.0;\n\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {LowLevelCallUtils} from \"./LowLevelCallUtils.sol\";\nimport {ENS} from \"../registry/ENS.sol\";\nimport {IExtendedResolver} from \"../resolvers/profiles/IExtendedResolver.sol\";\nimport {Resolver, INameResolver, IAddrResolver} from \"../resolvers/Resolver.sol\";\nimport {NameEncoder} from \"./NameEncoder.sol\";\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\nimport {HexUtils} from \"./HexUtils.sol\";\n\nerror OffchainLookup(\n address sender,\n string[] urls,\n bytes callData,\n bytes4 callbackFunction,\n bytes extraData\n);\n\nerror ResolverNotFound();\n\nerror ResolverWildcardNotSupported();\n\nerror ResolverNotContract();\n\nerror ResolverError(bytes returnData);\n\nerror HttpError(HttpErrorItem[] errors);\n\nstruct HttpErrorItem {\n uint16 status;\n string message;\n}\n\nstruct MulticallData {\n bytes name;\n bytes[] data;\n string[] gateways;\n bytes4 callbackFunction;\n bool isWildcard;\n address resolver;\n bytes metaData;\n bool[] failures;\n}\n\nstruct MulticallChecks {\n bool isCallback;\n bool hasExtendedResolver;\n}\n\nstruct OffchainLookupCallData {\n address sender;\n string[] urls;\n bytes callData;\n}\n\nstruct OffchainLookupExtraData {\n bytes4 callbackFunction;\n bytes data;\n}\n\nstruct Result {\n bool success;\n bytes returnData;\n}\n\ninterface BatchGateway {\n function query(\n OffchainLookupCallData[] memory data\n ) external returns (bool[] memory failures, bytes[] memory responses);\n}\n\n/**\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\n * making it possible to make a single smart contract call to resolve an ENS name.\n */\ncontract UniversalResolver is ERC165, Ownable {\n using Address for address;\n using NameEncoder for string;\n using BytesUtils for bytes;\n using HexUtils for bytes;\n\n string[] public batchGatewayURLs;\n ENS public immutable registry;\n\n constructor(address _registry, string[] memory _urls) {\n registry = ENS(_registry);\n batchGatewayURLs = _urls;\n }\n\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\n batchGatewayURLs = _urls;\n }\n\n /**\n * @dev Performs ENS name resolution for the supplied name and resolution data.\n * @param name The name to resolve, in normalised and DNS-encoded form.\n * @param data The resolution data, as specified in ENSIP-10.\n * @return The result of resolving the name.\n */\n function resolve(\n bytes calldata name,\n bytes memory data\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n batchGatewayURLs,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data\n ) external view returns (Result[] memory, address) {\n return resolve(name, data, batchGatewayURLs);\n }\n\n function resolve(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n gateways,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways\n ) public view returns (Result[] memory, address) {\n return\n _resolve(name, data, gateways, this.resolveCallback.selector, \"\");\n }\n\n function _resolveSingle(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) public view returns (bytes memory, address) {\n bytes[] memory dataArr = new bytes[](1);\n dataArr[0] = data;\n (Result[] memory results, address resolver) = _resolve(\n name,\n dataArr,\n gateways,\n callbackFunction,\n metaData\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function _resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) internal view returns (Result[] memory results, address resolverAddress) {\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\n resolverAddress = address(resolver);\n if (resolverAddress == address(0)) {\n revert ResolverNotFound();\n }\n\n if (!resolverAddress.isContract()) {\n revert ResolverNotContract();\n }\n\n bool isWildcard = finalOffset != 0;\n\n results = _multicall(\n MulticallData(\n name,\n data,\n gateways,\n callbackFunction,\n isWildcard,\n resolverAddress,\n metaData,\n new bool[](data.length)\n )\n );\n }\n\n function reverse(\n bytes calldata reverseName\n ) external view returns (string memory, address, address, address) {\n return reverse(reverseName, batchGatewayURLs);\n }\n\n /**\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\n */\n function reverse(\n bytes calldata reverseName,\n string[] memory gateways\n ) public view returns (string memory, address, address, address) {\n bytes memory encodedCall = abi.encodeCall(\n INameResolver.name,\n reverseName.namehash(0)\n );\n (\n bytes memory reverseResolvedData,\n address reverseResolverAddress\n ) = _resolveSingle(\n reverseName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n \"\"\n );\n\n return\n getForwardDataFromReverse(\n reverseResolvedData,\n reverseResolverAddress,\n gateways\n );\n }\n\n function getForwardDataFromReverse(\n bytes memory resolvedReverseData,\n address reverseResolverAddress,\n string[] memory gateways\n ) internal view returns (string memory, address, address, address) {\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\n\n (bytes memory encodedName, bytes32 namehash) = resolvedName\n .dnsEncodeName();\n\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\n bytes memory metaData = abi.encode(\n resolvedName,\n reverseResolverAddress\n );\n (bytes memory resolvedData, address resolverAddress) = this\n ._resolveSingle(\n encodedName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n metaData\n );\n\n address resolvedAddress = abi.decode(resolvedData, (address));\n\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n function resolveSingleCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (bytes memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveSingleCallback.selector\n );\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function resolveCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (Result[] memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveCallback.selector\n );\n return (results, resolver);\n }\n\n function reverseCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (string memory, address, address, address) {\n (\n Result[] memory results,\n address resolverAddress,\n string[] memory gateways,\n bytes memory metaData\n ) = _resolveCallback(\n response,\n extraData,\n this.reverseCallback.selector\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n if (metaData.length > 0) {\n (string memory resolvedName, address reverseResolverAddress) = abi\n .decode(metaData, (string, address));\n address resolvedAddress = abi.decode(result.returnData, (address));\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n return\n getForwardDataFromReverse(\n result.returnData,\n resolverAddress,\n gateways\n );\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override returns (bool) {\n return\n interfaceId == type(IExtendedResolver).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n function _resolveCallback(\n bytes calldata response,\n bytes calldata extraData,\n bytes4 callbackFunction\n )\n internal\n view\n returns (Result[] memory, address, string[] memory, bytes memory)\n {\n MulticallData memory multicallData;\n multicallData.callbackFunction = callbackFunction;\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\n response,\n (bool[], bytes[])\n );\n OffchainLookupExtraData[] memory extraDatas;\n (\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n ) = abi.decode(\n extraData,\n (bool, address, string[], bytes, OffchainLookupExtraData[])\n );\n require(responses.length <= extraDatas.length);\n multicallData.data = new bytes[](extraDatas.length);\n multicallData.failures = new bool[](extraDatas.length);\n uint256 offchainCount = 0;\n for (uint256 i = 0; i < extraDatas.length; i++) {\n if (extraDatas[i].callbackFunction == bytes4(0)) {\n // This call did not require an offchain lookup; use the previous input data.\n multicallData.data[i] = extraDatas[i].data;\n } else {\n if (failures[offchainCount]) {\n multicallData.failures[i] = true;\n multicallData.data[i] = responses[offchainCount];\n } else {\n multicallData.data[i] = abi.encodeWithSelector(\n extraDatas[i].callbackFunction,\n responses[offchainCount],\n extraDatas[i].data\n );\n }\n offchainCount = offchainCount + 1;\n }\n }\n\n return (\n _multicall(multicallData),\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData\n );\n }\n\n /**\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\n * the error with the data necessary to continue the request where it left off.\n * @param target The address to call.\n * @param data The data to call `target` with.\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\n * @return result Whether the call succeeded.\n */\n function callWithOffchainLookupPropagation(\n address target,\n bytes memory data,\n bool isSafe\n )\n internal\n view\n returns (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool result\n )\n {\n if (isSafe) {\n result = LowLevelCallUtils.functionStaticCall(target, data);\n } else {\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\n }\n uint256 size = LowLevelCallUtils.returnDataSize();\n\n if (result) {\n return (\n false,\n LowLevelCallUtils.readReturnData(0, size),\n extraData,\n true\n );\n }\n\n // Failure\n if (size >= 4) {\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\n // Offchain lookup. Decode the revert message and create our own that nests it.\n bytes memory revertData = LowLevelCallUtils.readReturnData(\n 4,\n size - 4\n );\n if (bytes4(errorId) == OffchainLookup.selector) {\n (\n address wrappedSender,\n string[] memory wrappedUrls,\n bytes memory wrappedCallData,\n bytes4 wrappedCallbackFunction,\n bytes memory wrappedExtraData\n ) = abi.decode(\n revertData,\n (address, string[], bytes, bytes4, bytes)\n );\n if (wrappedSender == target) {\n returnData = abi.encode(\n OffchainLookupCallData(\n wrappedSender,\n wrappedUrls,\n wrappedCallData\n )\n );\n extraData = OffchainLookupExtraData(\n wrappedCallbackFunction,\n wrappedExtraData\n );\n return (true, returnData, extraData, false);\n }\n } else {\n returnData = bytes.concat(errorId, revertData);\n return (false, returnData, extraData, false);\n }\n }\n }\n\n /**\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\n * removing labels until it finds a result.\n * @param name The name to resolve, in DNS-encoded and normalised form.\n * @return resolver The Resolver responsible for this name.\n * @return namehash The namehash of the full name.\n * @return finalOffset The offset of the first label with a resolver.\n */\n function findResolver(\n bytes calldata name\n ) public view returns (Resolver, bytes32, uint256) {\n (\n address resolver,\n bytes32 namehash,\n uint256 finalOffset\n ) = findResolver(name, 0);\n return (Resolver(resolver), namehash, finalOffset);\n }\n\n function findResolver(\n bytes calldata name,\n uint256 offset\n ) internal view returns (address, bytes32, uint256) {\n uint256 labelLength = uint256(uint8(name[offset]));\n if (labelLength == 0) {\n return (address(0), bytes32(0), offset);\n }\n uint256 nextLabel = offset + labelLength + 1;\n bytes32 labelHash;\n if (\n labelLength == 66 &&\n // 0x5b == '['\n name[offset + 1] == 0x5b &&\n // 0x5d == ']'\n name[nextLabel - 1] == 0x5d\n ) {\n // Encrypted label\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\n .hexStringToBytes32(0, 64);\n } else {\n labelHash = keccak256(name[offset + 1:nextLabel]);\n }\n (\n address parentresolver,\n bytes32 parentnode,\n uint256 parentoffset\n ) = findResolver(name, nextLabel);\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\n address resolver = registry.resolver(node);\n if (resolver != address(0)) {\n return (resolver, node, offset);\n }\n return (parentresolver, node, parentoffset);\n }\n\n function _checkInterface(\n address resolver,\n bytes4 interfaceId\n ) internal view returns (bool) {\n try\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\n returns (bool supported) {\n return supported;\n } catch {\n return false;\n }\n }\n\n function _checkSafetyAndItem(\n bytes memory name,\n bytes memory item,\n address resolver,\n MulticallChecks memory multicallChecks\n ) internal view returns (bool, bytes memory) {\n if (!multicallChecks.isCallback) {\n if (multicallChecks.hasExtendedResolver) {\n return (\n true,\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\n );\n }\n return (_checkInterface(resolver, bytes4(item)), item);\n }\n return (true, item);\n }\n\n function _checkMulticall(\n MulticallData memory multicallData\n ) internal view returns (MulticallChecks memory) {\n bool isCallback = multicallData.name.length == 0;\n bool hasExtendedResolver = _checkInterface(\n multicallData.resolver,\n type(IExtendedResolver).interfaceId\n );\n\n if (multicallData.isWildcard && !hasExtendedResolver) {\n revert ResolverWildcardNotSupported();\n }\n\n return MulticallChecks(isCallback, hasExtendedResolver);\n }\n\n function _checkResolveSingle(Result memory result) internal pure {\n if (!result.success) {\n if (bytes4(result.returnData) == HttpError.selector) {\n bytes memory returnData = result.returnData;\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n revert ResolverError(result.returnData);\n }\n }\n\n function _multicall(\n MulticallData memory multicallData\n ) internal view returns (Result[] memory results) {\n uint256 length = multicallData.data.length;\n uint256 offchainCount = 0;\n OffchainLookupCallData[]\n memory callDatas = new OffchainLookupCallData[](length);\n OffchainLookupExtraData[]\n memory extraDatas = new OffchainLookupExtraData[](length);\n results = new Result[](length);\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\n\n for (uint256 i = 0; i < length; i++) {\n bytes memory item = multicallData.data[i];\n bool failure = multicallData.failures[i];\n\n if (failure) {\n results[i] = Result(false, item);\n continue;\n }\n\n bool isSafe = false;\n (isSafe, item) = _checkSafetyAndItem(\n multicallData.name,\n item,\n multicallData.resolver,\n multicallChecks\n );\n\n (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool success\n ) = callWithOffchainLookupPropagation(\n multicallData.resolver,\n item,\n isSafe\n );\n\n if (offchain) {\n callDatas[offchainCount] = abi.decode(\n returnData,\n (OffchainLookupCallData)\n );\n extraDatas[i] = extraData;\n offchainCount += 1;\n continue;\n }\n\n if (success && multicallChecks.hasExtendedResolver) {\n // if this is a successful resolve() call, unwrap the result\n returnData = abi.decode(returnData, (bytes));\n }\n results[i] = Result(success, returnData);\n extraDatas[i].data = item;\n }\n\n if (offchainCount == 0) {\n return results;\n }\n\n // Trim callDatas if offchain data exists\n assembly {\n mstore(callDatas, offchainCount)\n }\n\n revert OffchainLookup(\n address(this),\n multicallData.gateways,\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\n multicallData.callbackFunction,\n abi.encode(\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n )\n );\n }\n}\n" + }, + "contracts/wrapper/BytesUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nlibrary BytesUtils {\n /*\n * @dev Returns the keccak-256 hash of a byte range.\n * @param self The byte string to hash.\n * @param offset The position to start hashing at.\n * @param len The number of bytes to hash.\n * @return The hash of the byte range.\n */\n function keccak(\n bytes memory self,\n uint256 offset,\n uint256 len\n ) internal pure returns (bytes32 ret) {\n require(offset + len <= self.length);\n assembly {\n ret := keccak256(add(add(self, 32), offset), len)\n }\n }\n\n /**\n * @dev Returns the ENS namehash of a DNS-encoded name.\n * @param self The DNS-encoded name to hash.\n * @param offset The offset at which to start hashing.\n * @return The namehash of the name.\n */\n function namehash(\n bytes memory self,\n uint256 offset\n ) internal pure returns (bytes32) {\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\n if (labelhash == bytes32(0)) {\n require(offset == self.length - 1, \"namehash: Junk at end of name\");\n return bytes32(0);\n }\n return\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\n }\n\n /**\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\n * @param self The byte string to read a label from.\n * @param idx The index to read a label at.\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\n * @return newIdx The index of the start of the next label.\n */\n function readLabel(\n bytes memory self,\n uint256 idx\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\n require(idx < self.length, \"readLabel: Index out of bounds\");\n uint256 len = uint256(uint8(self[idx]));\n if (len > 0) {\n labelhash = keccak(self, idx + 1, len);\n } else {\n labelhash = bytes32(0);\n }\n newIdx = idx + len + 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/holesky/UniversalResolver.json b/deployments/holesky/UniversalResolver.json index 32543763..db087126 100644 --- a/deployments/holesky/UniversalResolver.json +++ b/deployments/holesky/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0x2548a7E09deE955c4d97688dcB6C5b24085725f5", + "address": "0xa6ac935d4971e3cd133b950ae053becd16fe7f3b", "abi": [ { "inputs": [ @@ -596,48 +596,48 @@ "type": "function" } ], - "transactionHash": "0x3969575deb3b45337c5a67f49fc00ad5a52db5f3688b5f8039c32464c3db3247", + "transactionHash": "0xb980e95b4e6f861b8a385ef2d56da794c3b9ca4c2b0b431a960236520a69695e", "receipt": { "to": null, - "from": "0x4Fe4e666Be5752f1FdD210F4Ab5DE2Cc26e3E0e8", - "contractAddress": "0x2548a7E09deE955c4d97688dcB6C5b24085725f5", - "transactionIndex": 3, - "gasUsed": "3193145", - "logsBloom": "0x00000000000000000000000000000000000000000000200000800000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000100000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x7a7ba083a2a58240c554cbc7b461b1a94d877b33f7a26698ab6716874d242e53", - "transactionHash": "0x3969575deb3b45337c5a67f49fc00ad5a52db5f3688b5f8039c32464c3db3247", + "from": "0x69420f05a11f617b4b74ffe2e04b2d300dfa556f", + "contractAddress": "0xa6ac935d4971e3cd133b950ae053becd16fe7f3b", + "transactionIndex": "0x7", + "gasUsed": "0x2fe6fe", + "logsBloom": "0x00000000010000000000000000000000000000000000000200800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040800000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x46d110b455deb881ff400a506d42de71555bed49c210c6199e20714e625103f3", + "transactionHash": "0x3636f532779d76cd00117069e327819a854d9b5e7d97abe442ac19ba68187836", "logs": [ { - "transactionIndex": 3, - "blockNumber": 815385, - "transactionHash": "0x3969575deb3b45337c5a67f49fc00ad5a52db5f3688b5f8039c32464c3db3247", - "address": "0x2548a7E09deE955c4d97688dcB6C5b24085725f5", + "address": "0xa6ac935d4971e3cd133b950ae053becd16fe7f3b", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004fe4e666be5752f1fdd210f4ab5de2cc26e3e0e8" + "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], "data": "0x", - "logIndex": 0, - "blockHash": "0x7a7ba083a2a58240c554cbc7b461b1a94d877b33f7a26698ab6716874d242e53" + "blockNumber": "0xedaac", + "transactionHash": "0x3636f532779d76cd00117069e327819a854d9b5e7d97abe442ac19ba68187836", + "transactionIndex": "0x7", + "blockHash": "0x46d110b455deb881ff400a506d42de71555bed49c210c6199e20714e625103f3", + "logIndex": "0x10", + "removed": false } ], - "blockNumber": 815385, - "cumulativeGasUsed": "3256145", - "status": 1, - "byzantium": true + "blockNumber": "0xedaac", + "cumulativeGasUsed": "0x3afca3", + "status": "0x1" }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", [ - "https://universal-offchain-unwrapper.ens-cf.workers.dev/" + "https://ccip-v2.ens.xyz" ] ], - "numDeployments": 1, - "solcInputHash": "2286d90f0970dc1d34ef122ce5b9cee1", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n *\\n * Furthermore, `isContract` will also return true if the target contract within\\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\\n * which only has an effect at the end of a transaction.\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x006dd67219697fe68d7fbfdea512e7c4cb64a43565ed86171d67e844982da6fa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n uint256 hexLength = lastIdx - idx;\\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\\n revert(\\\"Invalid string length\\\");\\n }\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0x4a8a9c72d6f3effb80b310faa6dc273e7adbc3b949df9c7a42e290e5b13519f3\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n if (!result.success) {\\n revert ResolverError(result.returnData);\\n }\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = multicallData.data[i];\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0ba4e0ec4c2823f16c5d01402a605999a52a874311568025ba752d2d4db6af1d\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003b3638038062003b368339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613677620004bf600039600081816101ea015261150601526136776000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123fa565b610325565b60405190151581526020015b60405180910390f35b61017661017136600461261a565b61035c565b60405161015a9291906126f8565b6101976101923660046127a3565b610392565b60405161015a92919061280c565b6101b86101b3366004612895565b61047f565b60405161015a9493929190612901565b6101d061056f565b005b6101976101e036600461293d565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461299c565b6105ab565b6101d0610256366004612a62565b61064e565b610176610269366004612a9f565b61066d565b61028161027c366004612afe565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b40565b61078c565b60405161015a9190612b59565b6101b86102d4366004612b6c565b610838565b6101976102e7366004612895565b61092a565b6101766102fa366004612895565b61096e565b6101b861030d366004612afe565b6109e0565b6101d0610320366004612be0565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bfd565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bfd565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612c37565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612b59565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c92565b91509150600083602001518060200190518101906105319190612ce4565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612c37565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612c37565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b8051610669906001906020840190612327565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612bfd565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612bfd565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612bfd565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612bfd565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612c37565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612bfd565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612bfd565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612d0f565b90925090506060610bf98a8c018c612dc7565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d612460565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca0612460565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612c37565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612c37565b60200260200101516020015186602001518281518110610d4257610d42612c37565b6020026020010181905250610ea5565b848281518110610d6457610d64612c37565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612c37565b602002602001019015159081151581525050838281518110610dad57610dad612c37565b602002602001015186602001518281518110610dcb57610dcb612c37565b6020026020010181905250610e97565b828181518110610ded57610ded612c37565b602002602001015160000151848381518110610e0b57610e0b612c37565b6020026020010151848381518110610e2557610e25612c37565b602002602001015160200151604051602401610e42929190612f4b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612c37565b60200260200101819052505b610ea2826001612f8f565b91505b80610eaf81612fa2565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612fbb565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e91016126f8565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190613045565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c92565b915091506000828060200190518101906110349190612ce4565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c612460565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c3906130ae565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612b59565b60008060008086868681811061131757611317612c37565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f8f565b611352906001612f8f565b905060008260421480156113985750888861136e896001612f8f565b81811061137d5761137d612c37565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac6001856130e6565b8181106113bb576113bb612c37565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f8f565b906113fb6001896130e6565b92611408939291906130f9565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f8f565b611467928592906130f9565b604051611475929190613123565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612ce4565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611df4565b90925090508161162e57600185516115d491906130e6565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561169157611691612460565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d612460565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f612460565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611eab565b905060005b858110156119b6576000886020015182815181106117e8576117e8612c37565b6020026020010151905060008960e00151838151811061180a5761180a612c37565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612c37565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611f42565b80945081925050506000806000806118898f60a001518887611fca565b935093509350935083156118ff57828060200190518101906118ab91906131b3565b8b8d815181106118bd576118bd612c37565b6020026020010181905250818a89815181106118db576118db612c37565b60209081029190910101526118f160018d612f8f565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612fbb565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612c37565b60200260200101819052508e60200151888151811061197357611973612c37565b60200260200101518a898151811061198d5761198d612c37565b602002602001015160200181905250505050505050505b806119ae81612fa2565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb91906132ae565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c959493929190613310565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016133cd565b805160609060009081908490611a8e816002612f8f565b67ffffffffffffffff811115611aa657611aa6612460565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612c37565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612c37565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612c37565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff8816612182565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612c37565b602001015160f81c60f81b868260010181518110611c2757611c27612c37565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff8716612182565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612c37565b60008080611cae85856130e6565b905080604014158015611cc2575080602814155b80611cd75750611cd3600282613401565b6001145b15611d245760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e677468000000000000000000000060448201526064016104ec565b600191508551841115611d3657600080fd5b611d87565b6000603a8210602f83111615611d535750602f190190565b60478210604083111615611d6957506036190190565b60678210606083111615611d7f57506056190190565b5060ff919050565b60208601855b85811015611de957611da48183015160001a611d3b565b611db66001830184015160001a611d3b565b60ff811460ff83141715611dcf57600095505050611de9565b60049190911b1760089590951b9490941793600201611d8d565b505050935093915050565b60008083518310611e475760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611e5b57611e5b612c37565b016020015160f81c90508015611e8757611e8085611e7a866001612f8f565b83612182565b9250611e8c565b600092505b611e968185612f8f565b611ea1906001612f8f565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611ede90639061b92360e01b6121a6565b905083608001518015611eef575080155b15611f26576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611fbe57826020015115611fa25760018686604051602401611f6e929190612f4b565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611fb484611faf876130ae565b6121a6565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611ffd57611ff6878761222b565b905061200d565b61200a878761c35061223f565b90505b3d81156120315760006120216000836122d2565b9095509350600191506109219050565b60048110612178576000612047600060046122d2565b9050600061205f600461205a81866130e6565b6122d2565b9050630556f18360e41b612072836130ae565b6001600160e01b031916036121405760008060008060008580602001905181019061209d9190613423565b945094509450945094508e6001600160a01b0316856001600160a01b031603612136576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120f491906134d3565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612175565b81816040516020016121539291906134e6565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b82516000906121918385612f8f565b111561219c57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612218575060408051601f3d908101601f1916820190925261221591810190613515565b60015b61222457506000610356565b9050610356565b600061223883835a61223f565b9392505050565b60006001600160a01b0384163b6122be5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122ed576122ed612460565b6040519080825280601f01601f191660200182016040528015612317576020820181803683370190505b5090508183602083013e92915050565b82805482825590600052602060002090810192821561236d579160200282015b8281111561236d578251829061235d9082613581565b5091602001919060010190612347565b5061237992915061237d565b5090565b80821115612379576000612391828261239a565b5060010161237d565b5080546123a690612bfd565b6000825580601f106123b6575050565b601f016020900490600052602060002090810190610b6091905b8082111561237957600081556001016123d0565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561240c57600080fd5b8135612238816123e4565b60008083601f84011261242957600080fd5b50813567ffffffffffffffff81111561244157600080fd5b60208301915083602082850101111561245957600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561249957612499612460565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124c8576124c8612460565b604052919050565b600067ffffffffffffffff8211156124ea576124ea612460565b50601f01601f191660200190565b600061250b612506846124d0565b61249f565b905082815283838301111561251f57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261254757600080fd5b612238838335602085016124f8565b600067ffffffffffffffff82111561257057612570612460565b5060051b60200190565b600082601f83011261258b57600080fd5b8135602061259b61250683612556565b82815260059290921b840181019181810190868411156125ba57600080fd5b8286015b8481101561260f57803567ffffffffffffffff8111156125de5760008081fd5b8701603f810189136125f05760008081fd5b6126018986830135604084016124f8565b8452509183019183016125be565b509695505050505050565b6000806000806060858703121561263057600080fd5b843567ffffffffffffffff8082111561264857600080fd5b61265488838901612417565b9096509450602087013591508082111561266d57600080fd5b61267988838901612536565b9350604087013591508082111561268f57600080fd5b5061269c8782880161257a565b91505092959194509250565b60005b838110156126c35781810151838201526020016126ab565b50506000910152565b600081518084526126e48160208601602086016126a8565b601f01601f19169290920160200192915050565b60408152600061270b60408301856126cc565b90506001600160a01b03831660208301529392505050565b600082601f83011261273457600080fd5b8135602061274461250683612556565b82815260059290921b8401810191818101908684111561276357600080fd5b8286015b8481101561260f57803567ffffffffffffffff8111156127875760008081fd5b6127958986838b0101612536565b845250918301918301612767565b6000806000604084860312156127b857600080fd5b833567ffffffffffffffff808211156127d057600080fd5b6127dc87838801612417565b909550935060208601359150808211156127f557600080fd5b5061280286828701612723565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561287657888603605f190185528151805115158752830151838701889052612863888801826126cc565b9650509382019390820190600101612835565b50508395506001600160a01b0388168188015250505050509392505050565b600080600080604085870312156128ab57600080fd5b843567ffffffffffffffff808211156128c357600080fd5b6128cf88838901612417565b909650945060208701359150808211156128e857600080fd5b506128f587828801612417565b95989497509550505050565b60808152600061291460808301876126cc565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561295357600080fd5b843567ffffffffffffffff8082111561296b57600080fd5b61297788838901612417565b9096509450602087013591508082111561299057600080fd5b61267988838901612723565b60008060008060008060a087890312156129b557600080fd5b863567ffffffffffffffff808211156129cd57600080fd5b6129d98a838b01612417565b909850965060208901359150808211156129f257600080fd5b6129fe8a838b01612536565b95506040890135915080821115612a1457600080fd5b612a208a838b0161257a565b945060608901359150612a32826123e4565b90925060808801359080821115612a4857600080fd5b50612a5589828a01612536565b9150509295509295509295565b600060208284031215612a7457600080fd5b813567ffffffffffffffff811115612a8b57600080fd5b612a978482850161257a565b949350505050565b600080600060408486031215612ab457600080fd5b833567ffffffffffffffff80821115612acc57600080fd5b612ad887838801612417565b90955093506020860135915080821115612af157600080fd5b5061280286828701612536565b60008060208385031215612b1157600080fd5b823567ffffffffffffffff811115612b2857600080fd5b612b3485828601612417565b90969095509350505050565b600060208284031215612b5257600080fd5b5035919050565b60208152600061223860208301846126cc565b600080600060408486031215612b8157600080fd5b833567ffffffffffffffff80821115612b9957600080fd5b612ba587838801612417565b90955093506020860135915080821115612bbe57600080fd5b506128028682870161257a565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612bf257600080fd5b813561223881612bcb565b600181811c90821680612c1157607f821691505b602082108103612c3157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c5e57600080fd5b8151612c6c612506826124d0565b818152846020838601011115612c8157600080fd5b612a978260208301602087016126a8565b60008060408385031215612ca557600080fd5b825167ffffffffffffffff811115612cbc57600080fd5b612cc885828601612c4d565b9250506020830151612cd981612bcb565b809150509250929050565b600060208284031215612cf657600080fd5b815161223881612bcb565b8015158114610b6057600080fd5b60008060408385031215612d2257600080fd5b823567ffffffffffffffff80821115612d3a57600080fd5b818501915085601f830112612d4e57600080fd5b81356020612d5e61250683612556565b82815260059290921b84018101918181019089841115612d7d57600080fd5b948201945b83861015612da4578535612d9581612d01565b82529482019490820190612d82565b96505086013592505080821115612dba57600080fd5b50611ea185828601612723565b600080600080600060a08688031215612ddf57600080fd5b612de98635612d01565b85359450612dfa6020870135612bcb565b6020860135935067ffffffffffffffff8060408801351115612e1b57600080fd5b612e2b886040890135890161257a565b93508060608801351115612e3e57600080fd5b612e4e8860608901358901612536565b92508060808801351115612e6157600080fd5b6080870135870188601f820112612e7757600080fd5b612e846125068235612556565b81358082526020808301929160051b8401018b1015612ea257600080fd5b602083015b6020843560051b850101811015612f39578481351115612ec657600080fd5b803584016040818e03601f19011215612ede57600080fd5b612ee6612476565b612ef360208301356123e4565b602082013581528660408301351115612f0b57600080fd5b612f1e8e60206040850135850101612536565b60208201528085525050602083019250602081019050612ea7565b50809450505050509295509295909350565b604081526000612f5e60408301856126cc565b8281036020840152612f7081856126cc565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f79565b600060018201612fb457612fb4612f79565b5060010190565b600060208284031215612fcd57600080fd5b815167ffffffffffffffff811115612fe457600080fd5b612a9784828501612c4d565b600081518084526020808501808196508360051b8101915082860160005b858110156130385782840389526130268483516126cc565b9885019893509084019060010161300e565b5091979650505050505050565b60a08152600061305860a08301886126cc565b828103602084015261306a81886126cc565b9050828103604084015261307e8187612ff0565b90506001600160e01b03198516606084015282810360808401526130a281856126cc565b98975050505050505050565b6000815160208301516001600160e01b0319808216935060048310156130de5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612f79565b6000808585111561310957600080fd5b8386111561311657600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261314457600080fd5b8151602061315461250683612556565b82815260059290921b8401810191818101908684111561317357600080fd5b8286015b8481101561260f57805167ffffffffffffffff8111156131975760008081fd5b6131a58986838b0101612c4d565b845250918301918301613177565b6000602082840312156131c557600080fd5b815167ffffffffffffffff808211156131dd57600080fd5b90830190606082860312156131f157600080fd5b60405160608101818110838211171561320c5761320c612460565b604052825161321a81612bcb565b815260208301518281111561322e57600080fd5b61323a87828601613133565b60208301525060408301518281111561325257600080fd5b61325e87828601612c4d565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132956060850182612ff0565b905060408301518482036040860152612f7082826126cc565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561330357603f198886030184526132f185835161326d565b945092850192908501906001016132d5565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261333c60a0850188612ff0565b848103606086015261334e81886126cc565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156133ba57858303601f19018552815180516001600160e01b03191684528801518884018890526133a7888501826126cc565b9589019593505090870190600101613371565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133ef60a0830187612ff0565b828103604084015261307e81876126cc565b60008261341e57634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561343b57600080fd5b855161344681612bcb565b602087015190955067ffffffffffffffff8082111561346457600080fd5b61347089838a01613133565b9550604088015191508082111561348657600080fd5b61349289838a01612c4d565b9450606088015191506134a4826123e4565b6080880151919350808211156134b957600080fd5b506134c688828901612c4d565b9150509295509295909350565b602081526000612238602083018461326d565b600083516134f88184602088016126a8565b83519083019061350c8183602088016126a8565b01949350505050565b60006020828403121561352757600080fd5b815161223881612d01565b601f82111561357c57600081815260208120601f850160051c810160208610156135595750805b601f850160051c820191505b8181101561357857828155600101613565565b5050505b505050565b815167ffffffffffffffff81111561359b5761359b612460565b6135af816135a98454612bfd565b84613532565b602080601f8311600181146135e457600084156135cc5750858301515b600019600386901b1c1916600185901b178555613578565b600085815260208120601f198616915b82811015613613578886015182559484019460019091019084016135f4565b50858210156136315787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220ef521c6a2d77ddbbb252b6e6a0ebf0778121a37388eaee53a8a97682cbe23f7264736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123fa565b610325565b60405190151581526020015b60405180910390f35b61017661017136600461261a565b61035c565b60405161015a9291906126f8565b6101976101923660046127a3565b610392565b60405161015a92919061280c565b6101b86101b3366004612895565b61047f565b60405161015a9493929190612901565b6101d061056f565b005b6101976101e036600461293d565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461299c565b6105ab565b6101d0610256366004612a62565b61064e565b610176610269366004612a9f565b61066d565b61028161027c366004612afe565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b40565b61078c565b60405161015a9190612b59565b6101b86102d4366004612b6c565b610838565b6101976102e7366004612895565b61092a565b6101766102fa366004612895565b61096e565b6101b861030d366004612afe565b6109e0565b6101d0610320366004612be0565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bfd565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bfd565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612c37565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612b59565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c92565b91509150600083602001518060200190518101906105319190612ce4565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612c37565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612c37565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b8051610669906001906020840190612327565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612bfd565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612bfd565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612bfd565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612bfd565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612c37565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612bfd565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612bfd565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612d0f565b90925090506060610bf98a8c018c612dc7565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d612460565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca0612460565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612c37565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612c37565b60200260200101516020015186602001518281518110610d4257610d42612c37565b6020026020010181905250610ea5565b848281518110610d6457610d64612c37565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612c37565b602002602001019015159081151581525050838281518110610dad57610dad612c37565b602002602001015186602001518281518110610dcb57610dcb612c37565b6020026020010181905250610e97565b828181518110610ded57610ded612c37565b602002602001015160000151848381518110610e0b57610e0b612c37565b6020026020010151848381518110610e2557610e25612c37565b602002602001015160200151604051602401610e42929190612f4b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612c37565b60200260200101819052505b610ea2826001612f8f565b91505b80610eaf81612fa2565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612fbb565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e91016126f8565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190613045565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c92565b915091506000828060200190518101906110349190612ce4565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c612460565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c3906130ae565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612b59565b60008060008086868681811061131757611317612c37565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f8f565b611352906001612f8f565b905060008260421480156113985750888861136e896001612f8f565b81811061137d5761137d612c37565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac6001856130e6565b8181106113bb576113bb612c37565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f8f565b906113fb6001896130e6565b92611408939291906130f9565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f8f565b611467928592906130f9565b604051611475929190613123565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612ce4565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611df4565b90925090508161162e57600185516115d491906130e6565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561169157611691612460565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d612460565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f612460565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611eab565b905060005b858110156119b6576000886020015182815181106117e8576117e8612c37565b6020026020010151905060008960e00151838151811061180a5761180a612c37565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612c37565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611f42565b80945081925050506000806000806118898f60a001518887611fca565b935093509350935083156118ff57828060200190518101906118ab91906131b3565b8b8d815181106118bd576118bd612c37565b6020026020010181905250818a89815181106118db576118db612c37565b60209081029190910101526118f160018d612f8f565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612fbb565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612c37565b60200260200101819052508e60200151888151811061197357611973612c37565b60200260200101518a898151811061198d5761198d612c37565b602002602001015160200181905250505050505050505b806119ae81612fa2565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb91906132ae565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c959493929190613310565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016133cd565b805160609060009081908490611a8e816002612f8f565b67ffffffffffffffff811115611aa657611aa6612460565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612c37565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612c37565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612c37565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff8816612182565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612c37565b602001015160f81c60f81b868260010181518110611c2757611c27612c37565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff8716612182565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612c37565b60008080611cae85856130e6565b905080604014158015611cc2575080602814155b80611cd75750611cd3600282613401565b6001145b15611d245760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e677468000000000000000000000060448201526064016104ec565b600191508551841115611d3657600080fd5b611d87565b6000603a8210602f83111615611d535750602f190190565b60478210604083111615611d6957506036190190565b60678210606083111615611d7f57506056190190565b5060ff919050565b60208601855b85811015611de957611da48183015160001a611d3b565b611db66001830184015160001a611d3b565b60ff811460ff83141715611dcf57600095505050611de9565b60049190911b1760089590951b9490941793600201611d8d565b505050935093915050565b60008083518310611e475760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611e5b57611e5b612c37565b016020015160f81c90508015611e8757611e8085611e7a866001612f8f565b83612182565b9250611e8c565b600092505b611e968185612f8f565b611ea1906001612f8f565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611ede90639061b92360e01b6121a6565b905083608001518015611eef575080155b15611f26576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611fbe57826020015115611fa25760018686604051602401611f6e929190612f4b565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611fb484611faf876130ae565b6121a6565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611ffd57611ff6878761222b565b905061200d565b61200a878761c35061223f565b90505b3d81156120315760006120216000836122d2565b9095509350600191506109219050565b60048110612178576000612047600060046122d2565b9050600061205f600461205a81866130e6565b6122d2565b9050630556f18360e41b612072836130ae565b6001600160e01b031916036121405760008060008060008580602001905181019061209d9190613423565b945094509450945094508e6001600160a01b0316856001600160a01b031603612136576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120f491906134d3565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612175565b81816040516020016121539291906134e6565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b82516000906121918385612f8f565b111561219c57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612218575060408051601f3d908101601f1916820190925261221591810190613515565b60015b61222457506000610356565b9050610356565b600061223883835a61223f565b9392505050565b60006001600160a01b0384163b6122be5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122ed576122ed612460565b6040519080825280601f01601f191660200182016040528015612317576020820181803683370190505b5090508183602083013e92915050565b82805482825590600052602060002090810192821561236d579160200282015b8281111561236d578251829061235d9082613581565b5091602001919060010190612347565b5061237992915061237d565b5090565b80821115612379576000612391828261239a565b5060010161237d565b5080546123a690612bfd565b6000825580601f106123b6575050565b601f016020900490600052602060002090810190610b6091905b8082111561237957600081556001016123d0565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561240c57600080fd5b8135612238816123e4565b60008083601f84011261242957600080fd5b50813567ffffffffffffffff81111561244157600080fd5b60208301915083602082850101111561245957600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561249957612499612460565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124c8576124c8612460565b604052919050565b600067ffffffffffffffff8211156124ea576124ea612460565b50601f01601f191660200190565b600061250b612506846124d0565b61249f565b905082815283838301111561251f57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261254757600080fd5b612238838335602085016124f8565b600067ffffffffffffffff82111561257057612570612460565b5060051b60200190565b600082601f83011261258b57600080fd5b8135602061259b61250683612556565b82815260059290921b840181019181810190868411156125ba57600080fd5b8286015b8481101561260f57803567ffffffffffffffff8111156125de5760008081fd5b8701603f810189136125f05760008081fd5b6126018986830135604084016124f8565b8452509183019183016125be565b509695505050505050565b6000806000806060858703121561263057600080fd5b843567ffffffffffffffff8082111561264857600080fd5b61265488838901612417565b9096509450602087013591508082111561266d57600080fd5b61267988838901612536565b9350604087013591508082111561268f57600080fd5b5061269c8782880161257a565b91505092959194509250565b60005b838110156126c35781810151838201526020016126ab565b50506000910152565b600081518084526126e48160208601602086016126a8565b601f01601f19169290920160200192915050565b60408152600061270b60408301856126cc565b90506001600160a01b03831660208301529392505050565b600082601f83011261273457600080fd5b8135602061274461250683612556565b82815260059290921b8401810191818101908684111561276357600080fd5b8286015b8481101561260f57803567ffffffffffffffff8111156127875760008081fd5b6127958986838b0101612536565b845250918301918301612767565b6000806000604084860312156127b857600080fd5b833567ffffffffffffffff808211156127d057600080fd5b6127dc87838801612417565b909550935060208601359150808211156127f557600080fd5b5061280286828701612723565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561287657888603605f190185528151805115158752830151838701889052612863888801826126cc565b9650509382019390820190600101612835565b50508395506001600160a01b0388168188015250505050509392505050565b600080600080604085870312156128ab57600080fd5b843567ffffffffffffffff808211156128c357600080fd5b6128cf88838901612417565b909650945060208701359150808211156128e857600080fd5b506128f587828801612417565b95989497509550505050565b60808152600061291460808301876126cc565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561295357600080fd5b843567ffffffffffffffff8082111561296b57600080fd5b61297788838901612417565b9096509450602087013591508082111561299057600080fd5b61267988838901612723565b60008060008060008060a087890312156129b557600080fd5b863567ffffffffffffffff808211156129cd57600080fd5b6129d98a838b01612417565b909850965060208901359150808211156129f257600080fd5b6129fe8a838b01612536565b95506040890135915080821115612a1457600080fd5b612a208a838b0161257a565b945060608901359150612a32826123e4565b90925060808801359080821115612a4857600080fd5b50612a5589828a01612536565b9150509295509295509295565b600060208284031215612a7457600080fd5b813567ffffffffffffffff811115612a8b57600080fd5b612a978482850161257a565b949350505050565b600080600060408486031215612ab457600080fd5b833567ffffffffffffffff80821115612acc57600080fd5b612ad887838801612417565b90955093506020860135915080821115612af157600080fd5b5061280286828701612536565b60008060208385031215612b1157600080fd5b823567ffffffffffffffff811115612b2857600080fd5b612b3485828601612417565b90969095509350505050565b600060208284031215612b5257600080fd5b5035919050565b60208152600061223860208301846126cc565b600080600060408486031215612b8157600080fd5b833567ffffffffffffffff80821115612b9957600080fd5b612ba587838801612417565b90955093506020860135915080821115612bbe57600080fd5b506128028682870161257a565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612bf257600080fd5b813561223881612bcb565b600181811c90821680612c1157607f821691505b602082108103612c3157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c5e57600080fd5b8151612c6c612506826124d0565b818152846020838601011115612c8157600080fd5b612a978260208301602087016126a8565b60008060408385031215612ca557600080fd5b825167ffffffffffffffff811115612cbc57600080fd5b612cc885828601612c4d565b9250506020830151612cd981612bcb565b809150509250929050565b600060208284031215612cf657600080fd5b815161223881612bcb565b8015158114610b6057600080fd5b60008060408385031215612d2257600080fd5b823567ffffffffffffffff80821115612d3a57600080fd5b818501915085601f830112612d4e57600080fd5b81356020612d5e61250683612556565b82815260059290921b84018101918181019089841115612d7d57600080fd5b948201945b83861015612da4578535612d9581612d01565b82529482019490820190612d82565b96505086013592505080821115612dba57600080fd5b50611ea185828601612723565b600080600080600060a08688031215612ddf57600080fd5b612de98635612d01565b85359450612dfa6020870135612bcb565b6020860135935067ffffffffffffffff8060408801351115612e1b57600080fd5b612e2b886040890135890161257a565b93508060608801351115612e3e57600080fd5b612e4e8860608901358901612536565b92508060808801351115612e6157600080fd5b6080870135870188601f820112612e7757600080fd5b612e846125068235612556565b81358082526020808301929160051b8401018b1015612ea257600080fd5b602083015b6020843560051b850101811015612f39578481351115612ec657600080fd5b803584016040818e03601f19011215612ede57600080fd5b612ee6612476565b612ef360208301356123e4565b602082013581528660408301351115612f0b57600080fd5b612f1e8e60206040850135850101612536565b60208201528085525050602083019250602081019050612ea7565b50809450505050509295509295909350565b604081526000612f5e60408301856126cc565b8281036020840152612f7081856126cc565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f79565b600060018201612fb457612fb4612f79565b5060010190565b600060208284031215612fcd57600080fd5b815167ffffffffffffffff811115612fe457600080fd5b612a9784828501612c4d565b600081518084526020808501808196508360051b8101915082860160005b858110156130385782840389526130268483516126cc565b9885019893509084019060010161300e565b5091979650505050505050565b60a08152600061305860a08301886126cc565b828103602084015261306a81886126cc565b9050828103604084015261307e8187612ff0565b90506001600160e01b03198516606084015282810360808401526130a281856126cc565b98975050505050505050565b6000815160208301516001600160e01b0319808216935060048310156130de5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612f79565b6000808585111561310957600080fd5b8386111561311657600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261314457600080fd5b8151602061315461250683612556565b82815260059290921b8401810191818101908684111561317357600080fd5b8286015b8481101561260f57805167ffffffffffffffff8111156131975760008081fd5b6131a58986838b0101612c4d565b845250918301918301613177565b6000602082840312156131c557600080fd5b815167ffffffffffffffff808211156131dd57600080fd5b90830190606082860312156131f157600080fd5b60405160608101818110838211171561320c5761320c612460565b604052825161321a81612bcb565b815260208301518281111561322e57600080fd5b61323a87828601613133565b60208301525060408301518281111561325257600080fd5b61325e87828601612c4d565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132956060850182612ff0565b905060408301518482036040860152612f7082826126cc565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561330357603f198886030184526132f185835161326d565b945092850192908501906001016132d5565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261333c60a0850188612ff0565b848103606086015261334e81886126cc565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156133ba57858303601f19018552815180516001600160e01b03191684528801518884018890526133a7888501826126cc565b9589019593505090870190600101613371565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133ef60a0830187612ff0565b828103604084015261307e81876126cc565b60008261341e57634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561343b57600080fd5b855161344681612bcb565b602087015190955067ffffffffffffffff8082111561346457600080fd5b61347089838a01613133565b9550604088015191508082111561348657600080fd5b61349289838a01612c4d565b9450606088015191506134a4826123e4565b6080880151919350808211156134b957600080fd5b506134c688828901612c4d565b9150509295509295909350565b602081526000612238602083018461326d565b600083516134f88184602088016126a8565b83519083019061350c8183602088016126a8565b01949350505050565b60006020828403121561352757600080fd5b815161223881612d01565b601f82111561357c57600081815260208120601f850160051c810160208610156135595750805b601f850160051c820191505b8181101561357857828155600101613565565b5050505b505050565b815167ffffffffffffffff81111561359b5761359b612460565b6135af816135a98454612bfd565b84613532565b602080601f8311600181146135e457600084156135cc5750858301515b600019600386901b1c1916600185901b178555613578565b600085815260208120601f198616915b82811015613613578886015182559484019460019091019084016135f4565b50858210156136315787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220ef521c6a2d77ddbbb252b6e6a0ebf0778121a37388eaee53a8a97682cbe23f7264736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "49f758ec505ff69b72f3179ac11d7cfc", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n uint256 hexLength = lastIdx - idx;\\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\\n revert(\\\"Invalid string length\\\");\\n }\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0x4a8a9c72d6f3effb80b310faa6dc273e7adbc3b949df9c7a42e290e5b13519f3\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = item;\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2a03a3a94a411b599690e58634c2c5695561cbe4a16fae60cbfefa872a6c2f7b\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003b0f38038062003b0f8339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613650620004bf600039600081816101ea01526114fc01526136506000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -656,7 +656,7 @@ "details": "Returns the address of the current owner." }, "renounceOwnership()": { - "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner." }, "resolve(bytes,bytes)": { "details": "Performs ENS name resolution for the supplied name and resolution data.", @@ -695,7 +695,7 @@ "storageLayout": { "storage": [ { - "astId": 444, + "astId": 7, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "_owner", "offset": 0, @@ -703,7 +703,7 @@ "type": "t_address" }, { - "astId": 19400, + "astId": 1537, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "batchGatewayURLs", "offset": 0, diff --git a/deployments/holesky/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json b/deployments/holesky/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json new file mode 100644 index 00000000..51bd8239 --- /dev/null +++ b/deployments/holesky/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json @@ -0,0 +1,101 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/registry/ENS.sol": { + "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n // Logged when the owner of a node assigns a new owner to a subnode.\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n // Logged when the owner of a node transfers ownership to a new account.\n event Transfer(bytes32 indexed node, address owner);\n\n // Logged when the resolver for a node changes.\n event NewResolver(bytes32 indexed node, address resolver);\n\n // Logged when the TTL of a node changes\n event NewTTL(bytes32 indexed node, uint64 ttl);\n\n // Logged when an operator is added or removed.\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n function setRecord(\n bytes32 node,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner\n ) external returns (bytes32);\n\n function setResolver(bytes32 node, address resolver) external;\n\n function setOwner(bytes32 node, address owner) external;\n\n function setTTL(bytes32 node, uint64 ttl) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function owner(bytes32 node) external view returns (address);\n\n function resolver(bytes32 node) external view returns (address);\n\n function ttl(bytes32 node) external view returns (uint64);\n\n function recordExists(bytes32 node) external view returns (bool);\n\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/resolvers/profiles/IABIResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IABIResolver {\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\n\n /**\n * Returns the ABI associated with an ENS node.\n * Defined in EIP205.\n * @param node The ENS node to query\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\n * @return contentType The content type of the return value\n * @return data The ABI data\n */\n function ABI(\n bytes32 node,\n uint256 contentTypes\n ) external view returns (uint256, bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddressResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the new (multicoin) addr function.\n */\ninterface IAddressResolver {\n event AddressChanged(\n bytes32 indexed node,\n uint256 coinType,\n bytes newAddress\n );\n\n function addr(\n bytes32 node,\n uint256 coinType\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddrResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the legacy (ETH-only) addr function.\n */\ninterface IAddrResolver {\n event AddrChanged(bytes32 indexed node, address a);\n\n /**\n * Returns the address associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated address.\n */\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "contracts/resolvers/profiles/IContentHashResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IContentHashResolver {\n event ContenthashChanged(bytes32 indexed node, bytes hash);\n\n /**\n * Returns the contenthash associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function contenthash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSRecordResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSRecordResolver {\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\n event DNSRecordChanged(\n bytes32 indexed node,\n bytes name,\n uint16 resource,\n bytes record\n );\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\n\n /**\n * Obtain a DNS record.\n * @param node the namehash of the node for which to fetch the record\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\n * @return the DNS record in wire format if present, otherwise empty\n */\n function dnsRecord(\n bytes32 node,\n bytes32 name,\n uint16 resource\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSZoneResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSZoneResolver {\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\n event DNSZonehashChanged(\n bytes32 indexed node,\n bytes lastzonehash,\n bytes zonehash\n );\n\n /**\n * zonehash obtains the hash for the zone.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function zonehash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IExtendedResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n function resolve(\n bytes memory name,\n bytes memory data\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IInterfaceResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IInterfaceResolver {\n event InterfaceChanged(\n bytes32 indexed node,\n bytes4 indexed interfaceID,\n address implementer\n );\n\n /**\n * Returns the address of a contract that implements the specified interface for this name.\n * If an implementer has not been set for this interfaceID and name, the resolver will query\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\n * will be returned.\n * @param node The ENS node to query.\n * @param interfaceID The EIP 165 interface ID to check for.\n * @return The address that implements this interface, or 0 if the interface is unsupported.\n */\n function interfaceImplementer(\n bytes32 node,\n bytes4 interfaceID\n ) external view returns (address);\n}\n" + }, + "contracts/resolvers/profiles/INameResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface INameResolver {\n event NameChanged(bytes32 indexed node, string name);\n\n /**\n * Returns the name associated with an ENS node, for reverse records.\n * Defined in EIP181.\n * @param node The ENS node to query.\n * @return The associated name.\n */\n function name(bytes32 node) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/profiles/IPubkeyResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IPubkeyResolver {\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\n\n /**\n * Returns the SECP256k1 public key associated with an ENS node.\n * Defined in EIP 619.\n * @param node The ENS node to query\n * @return x The X coordinate of the curve point for the public key.\n * @return y The Y coordinate of the curve point for the public key.\n */\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\n}\n" + }, + "contracts/resolvers/profiles/ITextResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface ITextResolver {\n event TextChanged(\n bytes32 indexed node,\n string indexed indexedKey,\n string key,\n string value\n );\n\n /**\n * Returns the text data associated with an ENS node and key.\n * @param node The ENS node to query.\n * @param key The text data key to query.\n * @return The associated text data.\n */\n function text(\n bytes32 node,\n string calldata key\n ) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/Resolver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./profiles/IABIResolver.sol\";\nimport \"./profiles/IAddressResolver.sol\";\nimport \"./profiles/IAddrResolver.sol\";\nimport \"./profiles/IContentHashResolver.sol\";\nimport \"./profiles/IDNSRecordResolver.sol\";\nimport \"./profiles/IDNSZoneResolver.sol\";\nimport \"./profiles/IInterfaceResolver.sol\";\nimport \"./profiles/INameResolver.sol\";\nimport \"./profiles/IPubkeyResolver.sol\";\nimport \"./profiles/ITextResolver.sol\";\nimport \"./profiles/IExtendedResolver.sol\";\n\n/**\n * A generic resolver interface which includes all the functions including the ones deprecated\n */\ninterface Resolver is\n IERC165,\n IABIResolver,\n IAddressResolver,\n IAddrResolver,\n IContentHashResolver,\n IDNSRecordResolver,\n IDNSZoneResolver,\n IInterfaceResolver,\n INameResolver,\n IPubkeyResolver,\n ITextResolver,\n IExtendedResolver\n{\n /* Deprecated events */\n event ContentChanged(bytes32 indexed node, bytes32 hash);\n\n function setApprovalForAll(address, bool) external;\n\n function approve(bytes32 node, address delegate, bool approved) external;\n\n function isApprovedForAll(address account, address operator) external;\n\n function isApprovedFor(\n address owner,\n bytes32 node,\n address delegate\n ) external;\n\n function setABI(\n bytes32 node,\n uint256 contentType,\n bytes calldata data\n ) external;\n\n function setAddr(bytes32 node, address addr) external;\n\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\n\n function setContenthash(bytes32 node, bytes calldata hash) external;\n\n function setDnsrr(bytes32 node, bytes calldata data) external;\n\n function setName(bytes32 node, string calldata _name) external;\n\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\n\n function setText(\n bytes32 node,\n string calldata key,\n string calldata value\n ) external;\n\n function setInterface(\n bytes32 node,\n bytes4 interfaceID,\n address implementer\n ) external;\n\n function multicall(\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n function multicallWithNodeCheck(\n bytes32 nodehash,\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n /* Deprecated functions */\n function content(bytes32 node) external view returns (bytes32);\n\n function multihash(bytes32 node) external view returns (bytes memory);\n\n function setContent(bytes32 node, bytes32 hash) external;\n\n function setMultihash(bytes32 node, bytes calldata hash) external;\n}\n" + }, + "contracts/utils/HexUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nlibrary HexUtils {\n /**\n * @dev Attempts to parse bytes32 from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexStringToBytes32(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (bytes32 r, bool valid) {\n uint256 hexLength = lastIdx - idx;\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\n revert(\"Invalid string length\");\n }\n valid = true;\n assembly {\n // check that the index to read to is not past the end of the string\n if gt(lastIdx, mload(str)) {\n revert(0, 0)\n }\n\n function getHex(c) -> ascii {\n // chars 48-57: 0-9\n if and(gt(c, 47), lt(c, 58)) {\n ascii := sub(c, 48)\n leave\n }\n // chars 65-70: A-F\n if and(gt(c, 64), lt(c, 71)) {\n ascii := add(sub(c, 65), 10)\n leave\n }\n // chars 97-102: a-f\n if and(gt(c, 96), lt(c, 103)) {\n ascii := add(sub(c, 97), 10)\n leave\n }\n // invalid char\n ascii := 0xff\n }\n\n let ptr := add(str, 32)\n for {\n let i := idx\n } lt(i, lastIdx) {\n i := add(i, 2)\n } {\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\n // if either byte is invalid, set invalid and break loop\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\n valid := false\n break\n }\n let combined := or(shl(4, byte1), byte2)\n r := or(shl(8, r), combined)\n }\n }\n }\n\n /**\n * @dev Attempts to parse an address from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexToAddress(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (address, bool) {\n if (lastIdx - idx < 40) return (address(0x0), false);\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\n return (address(uint160(uint256(r))), valid);\n }\n}\n" + }, + "contracts/utils/LowLevelCallUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nlibrary LowLevelCallUtils {\n using Address for address;\n\n /**\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data\n ) internal view returns (bool success) {\n return functionStaticCall(target, data, gasleft());\n }\n\n /**\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @param gasLimit The gas limit to use for the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n uint256 gasLimit\n ) internal view returns (bool success) {\n require(\n target.isContract(),\n \"LowLevelCallUtils: static call to non-contract\"\n );\n assembly {\n success := staticcall(\n gasLimit,\n target,\n add(data, 32),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n /**\n * @dev Returns the size of the return data of the most recent external call.\n */\n function returnDataSize() internal pure returns (uint256 len) {\n assembly {\n len := returndatasize()\n }\n }\n\n /**\n * @dev Reads return data from the most recent external call.\n * @param offset Offset into the return data.\n * @param length Number of bytes to return.\n */\n function readReturnData(\n uint256 offset,\n uint256 length\n ) internal pure returns (bytes memory data) {\n data = new bytes(length);\n assembly {\n returndatacopy(add(data, 32), offset, length)\n }\n }\n\n /**\n * @dev Reverts with the return data from the most recent external call.\n */\n function propagateRevert() internal pure {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n}\n" + }, + "contracts/utils/NameEncoder.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\n\nlibrary NameEncoder {\n using BytesUtils for bytes;\n\n function dnsEncodeName(\n string memory name\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\n uint8 labelLength = 0;\n bytes memory bytesName = bytes(name);\n uint256 length = bytesName.length;\n dnsName = new bytes(length + 2);\n node = 0;\n if (length == 0) {\n dnsName[0] = 0;\n return (dnsName, node);\n }\n\n // use unchecked to save gas since we check for an underflow\n // and we check for the length before the loop\n unchecked {\n for (uint256 i = length - 1; i >= 0; i--) {\n if (bytesName[i] == \".\") {\n dnsName[i + 1] = bytes1(labelLength);\n node = keccak256(\n abi.encodePacked(\n node,\n bytesName.keccak(i + 1, labelLength)\n )\n );\n labelLength = 0;\n } else {\n labelLength += 1;\n dnsName[i + 1] = bytesName[i];\n }\n if (i == 0) {\n break;\n }\n }\n }\n\n node = keccak256(\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\n );\n\n dnsName[0] = bytes1(labelLength);\n return (dnsName, node);\n }\n}\n" + }, + "contracts/utils/UniversalResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17 <0.9.0;\n\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {LowLevelCallUtils} from \"./LowLevelCallUtils.sol\";\nimport {ENS} from \"../registry/ENS.sol\";\nimport {IExtendedResolver} from \"../resolvers/profiles/IExtendedResolver.sol\";\nimport {Resolver, INameResolver, IAddrResolver} from \"../resolvers/Resolver.sol\";\nimport {NameEncoder} from \"./NameEncoder.sol\";\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\nimport {HexUtils} from \"./HexUtils.sol\";\n\nerror OffchainLookup(\n address sender,\n string[] urls,\n bytes callData,\n bytes4 callbackFunction,\n bytes extraData\n);\n\nerror ResolverNotFound();\n\nerror ResolverWildcardNotSupported();\n\nerror ResolverNotContract();\n\nerror ResolverError(bytes returnData);\n\nerror HttpError(HttpErrorItem[] errors);\n\nstruct HttpErrorItem {\n uint16 status;\n string message;\n}\n\nstruct MulticallData {\n bytes name;\n bytes[] data;\n string[] gateways;\n bytes4 callbackFunction;\n bool isWildcard;\n address resolver;\n bytes metaData;\n bool[] failures;\n}\n\nstruct MulticallChecks {\n bool isCallback;\n bool hasExtendedResolver;\n}\n\nstruct OffchainLookupCallData {\n address sender;\n string[] urls;\n bytes callData;\n}\n\nstruct OffchainLookupExtraData {\n bytes4 callbackFunction;\n bytes data;\n}\n\nstruct Result {\n bool success;\n bytes returnData;\n}\n\ninterface BatchGateway {\n function query(\n OffchainLookupCallData[] memory data\n ) external returns (bool[] memory failures, bytes[] memory responses);\n}\n\n/**\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\n * making it possible to make a single smart contract call to resolve an ENS name.\n */\ncontract UniversalResolver is ERC165, Ownable {\n using Address for address;\n using NameEncoder for string;\n using BytesUtils for bytes;\n using HexUtils for bytes;\n\n string[] public batchGatewayURLs;\n ENS public immutable registry;\n\n constructor(address _registry, string[] memory _urls) {\n registry = ENS(_registry);\n batchGatewayURLs = _urls;\n }\n\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\n batchGatewayURLs = _urls;\n }\n\n /**\n * @dev Performs ENS name resolution for the supplied name and resolution data.\n * @param name The name to resolve, in normalised and DNS-encoded form.\n * @param data The resolution data, as specified in ENSIP-10.\n * @return The result of resolving the name.\n */\n function resolve(\n bytes calldata name,\n bytes memory data\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n batchGatewayURLs,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data\n ) external view returns (Result[] memory, address) {\n return resolve(name, data, batchGatewayURLs);\n }\n\n function resolve(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n gateways,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways\n ) public view returns (Result[] memory, address) {\n return\n _resolve(name, data, gateways, this.resolveCallback.selector, \"\");\n }\n\n function _resolveSingle(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) public view returns (bytes memory, address) {\n bytes[] memory dataArr = new bytes[](1);\n dataArr[0] = data;\n (Result[] memory results, address resolver) = _resolve(\n name,\n dataArr,\n gateways,\n callbackFunction,\n metaData\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function _resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) internal view returns (Result[] memory results, address resolverAddress) {\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\n resolverAddress = address(resolver);\n if (resolverAddress == address(0)) {\n revert ResolverNotFound();\n }\n\n if (!resolverAddress.isContract()) {\n revert ResolverNotContract();\n }\n\n bool isWildcard = finalOffset != 0;\n\n results = _multicall(\n MulticallData(\n name,\n data,\n gateways,\n callbackFunction,\n isWildcard,\n resolverAddress,\n metaData,\n new bool[](data.length)\n )\n );\n }\n\n function reverse(\n bytes calldata reverseName\n ) external view returns (string memory, address, address, address) {\n return reverse(reverseName, batchGatewayURLs);\n }\n\n /**\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\n */\n function reverse(\n bytes calldata reverseName,\n string[] memory gateways\n ) public view returns (string memory, address, address, address) {\n bytes memory encodedCall = abi.encodeCall(\n INameResolver.name,\n reverseName.namehash(0)\n );\n (\n bytes memory reverseResolvedData,\n address reverseResolverAddress\n ) = _resolveSingle(\n reverseName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n \"\"\n );\n\n return\n getForwardDataFromReverse(\n reverseResolvedData,\n reverseResolverAddress,\n gateways\n );\n }\n\n function getForwardDataFromReverse(\n bytes memory resolvedReverseData,\n address reverseResolverAddress,\n string[] memory gateways\n ) internal view returns (string memory, address, address, address) {\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\n\n (bytes memory encodedName, bytes32 namehash) = resolvedName\n .dnsEncodeName();\n\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\n bytes memory metaData = abi.encode(\n resolvedName,\n reverseResolverAddress\n );\n (bytes memory resolvedData, address resolverAddress) = this\n ._resolveSingle(\n encodedName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n metaData\n );\n\n address resolvedAddress = abi.decode(resolvedData, (address));\n\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n function resolveSingleCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (bytes memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveSingleCallback.selector\n );\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function resolveCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (Result[] memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveCallback.selector\n );\n return (results, resolver);\n }\n\n function reverseCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (string memory, address, address, address) {\n (\n Result[] memory results,\n address resolverAddress,\n string[] memory gateways,\n bytes memory metaData\n ) = _resolveCallback(\n response,\n extraData,\n this.reverseCallback.selector\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n if (metaData.length > 0) {\n (string memory resolvedName, address reverseResolverAddress) = abi\n .decode(metaData, (string, address));\n address resolvedAddress = abi.decode(result.returnData, (address));\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n return\n getForwardDataFromReverse(\n result.returnData,\n resolverAddress,\n gateways\n );\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override returns (bool) {\n return\n interfaceId == type(IExtendedResolver).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n function _resolveCallback(\n bytes calldata response,\n bytes calldata extraData,\n bytes4 callbackFunction\n )\n internal\n view\n returns (Result[] memory, address, string[] memory, bytes memory)\n {\n MulticallData memory multicallData;\n multicallData.callbackFunction = callbackFunction;\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\n response,\n (bool[], bytes[])\n );\n OffchainLookupExtraData[] memory extraDatas;\n (\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n ) = abi.decode(\n extraData,\n (bool, address, string[], bytes, OffchainLookupExtraData[])\n );\n require(responses.length <= extraDatas.length);\n multicallData.data = new bytes[](extraDatas.length);\n multicallData.failures = new bool[](extraDatas.length);\n uint256 offchainCount = 0;\n for (uint256 i = 0; i < extraDatas.length; i++) {\n if (extraDatas[i].callbackFunction == bytes4(0)) {\n // This call did not require an offchain lookup; use the previous input data.\n multicallData.data[i] = extraDatas[i].data;\n } else {\n if (failures[offchainCount]) {\n multicallData.failures[i] = true;\n multicallData.data[i] = responses[offchainCount];\n } else {\n multicallData.data[i] = abi.encodeWithSelector(\n extraDatas[i].callbackFunction,\n responses[offchainCount],\n extraDatas[i].data\n );\n }\n offchainCount = offchainCount + 1;\n }\n }\n\n return (\n _multicall(multicallData),\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData\n );\n }\n\n /**\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\n * the error with the data necessary to continue the request where it left off.\n * @param target The address to call.\n * @param data The data to call `target` with.\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\n * @return result Whether the call succeeded.\n */\n function callWithOffchainLookupPropagation(\n address target,\n bytes memory data,\n bool isSafe\n )\n internal\n view\n returns (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool result\n )\n {\n if (isSafe) {\n result = LowLevelCallUtils.functionStaticCall(target, data);\n } else {\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\n }\n uint256 size = LowLevelCallUtils.returnDataSize();\n\n if (result) {\n return (\n false,\n LowLevelCallUtils.readReturnData(0, size),\n extraData,\n true\n );\n }\n\n // Failure\n if (size >= 4) {\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\n // Offchain lookup. Decode the revert message and create our own that nests it.\n bytes memory revertData = LowLevelCallUtils.readReturnData(\n 4,\n size - 4\n );\n if (bytes4(errorId) == OffchainLookup.selector) {\n (\n address wrappedSender,\n string[] memory wrappedUrls,\n bytes memory wrappedCallData,\n bytes4 wrappedCallbackFunction,\n bytes memory wrappedExtraData\n ) = abi.decode(\n revertData,\n (address, string[], bytes, bytes4, bytes)\n );\n if (wrappedSender == target) {\n returnData = abi.encode(\n OffchainLookupCallData(\n wrappedSender,\n wrappedUrls,\n wrappedCallData\n )\n );\n extraData = OffchainLookupExtraData(\n wrappedCallbackFunction,\n wrappedExtraData\n );\n return (true, returnData, extraData, false);\n }\n } else {\n returnData = bytes.concat(errorId, revertData);\n return (false, returnData, extraData, false);\n }\n }\n }\n\n /**\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\n * removing labels until it finds a result.\n * @param name The name to resolve, in DNS-encoded and normalised form.\n * @return resolver The Resolver responsible for this name.\n * @return namehash The namehash of the full name.\n * @return finalOffset The offset of the first label with a resolver.\n */\n function findResolver(\n bytes calldata name\n ) public view returns (Resolver, bytes32, uint256) {\n (\n address resolver,\n bytes32 namehash,\n uint256 finalOffset\n ) = findResolver(name, 0);\n return (Resolver(resolver), namehash, finalOffset);\n }\n\n function findResolver(\n bytes calldata name,\n uint256 offset\n ) internal view returns (address, bytes32, uint256) {\n uint256 labelLength = uint256(uint8(name[offset]));\n if (labelLength == 0) {\n return (address(0), bytes32(0), offset);\n }\n uint256 nextLabel = offset + labelLength + 1;\n bytes32 labelHash;\n if (\n labelLength == 66 &&\n // 0x5b == '['\n name[offset + 1] == 0x5b &&\n // 0x5d == ']'\n name[nextLabel - 1] == 0x5d\n ) {\n // Encrypted label\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\n .hexStringToBytes32(0, 64);\n } else {\n labelHash = keccak256(name[offset + 1:nextLabel]);\n }\n (\n address parentresolver,\n bytes32 parentnode,\n uint256 parentoffset\n ) = findResolver(name, nextLabel);\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\n address resolver = registry.resolver(node);\n if (resolver != address(0)) {\n return (resolver, node, offset);\n }\n return (parentresolver, node, parentoffset);\n }\n\n function _checkInterface(\n address resolver,\n bytes4 interfaceId\n ) internal view returns (bool) {\n try\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\n returns (bool supported) {\n return supported;\n } catch {\n return false;\n }\n }\n\n function _checkSafetyAndItem(\n bytes memory name,\n bytes memory item,\n address resolver,\n MulticallChecks memory multicallChecks\n ) internal view returns (bool, bytes memory) {\n if (!multicallChecks.isCallback) {\n if (multicallChecks.hasExtendedResolver) {\n return (\n true,\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\n );\n }\n return (_checkInterface(resolver, bytes4(item)), item);\n }\n return (true, item);\n }\n\n function _checkMulticall(\n MulticallData memory multicallData\n ) internal view returns (MulticallChecks memory) {\n bool isCallback = multicallData.name.length == 0;\n bool hasExtendedResolver = _checkInterface(\n multicallData.resolver,\n type(IExtendedResolver).interfaceId\n );\n\n if (multicallData.isWildcard && !hasExtendedResolver) {\n revert ResolverWildcardNotSupported();\n }\n\n return MulticallChecks(isCallback, hasExtendedResolver);\n }\n\n function _checkResolveSingle(Result memory result) internal pure {\n if (!result.success) {\n if (bytes4(result.returnData) == HttpError.selector) {\n bytes memory returnData = result.returnData;\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n revert ResolverError(result.returnData);\n }\n }\n\n function _multicall(\n MulticallData memory multicallData\n ) internal view returns (Result[] memory results) {\n uint256 length = multicallData.data.length;\n uint256 offchainCount = 0;\n OffchainLookupCallData[]\n memory callDatas = new OffchainLookupCallData[](length);\n OffchainLookupExtraData[]\n memory extraDatas = new OffchainLookupExtraData[](length);\n results = new Result[](length);\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\n\n for (uint256 i = 0; i < length; i++) {\n bytes memory item = multicallData.data[i];\n bool failure = multicallData.failures[i];\n\n if (failure) {\n results[i] = Result(false, item);\n continue;\n }\n\n bool isSafe = false;\n (isSafe, item) = _checkSafetyAndItem(\n multicallData.name,\n item,\n multicallData.resolver,\n multicallChecks\n );\n\n (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool success\n ) = callWithOffchainLookupPropagation(\n multicallData.resolver,\n item,\n isSafe\n );\n\n if (offchain) {\n callDatas[offchainCount] = abi.decode(\n returnData,\n (OffchainLookupCallData)\n );\n extraDatas[i] = extraData;\n offchainCount += 1;\n continue;\n }\n\n if (success && multicallChecks.hasExtendedResolver) {\n // if this is a successful resolve() call, unwrap the result\n returnData = abi.decode(returnData, (bytes));\n }\n results[i] = Result(success, returnData);\n extraDatas[i].data = item;\n }\n\n if (offchainCount == 0) {\n return results;\n }\n\n // Trim callDatas if offchain data exists\n assembly {\n mstore(callDatas, offchainCount)\n }\n\n revert OffchainLookup(\n address(this),\n multicallData.gateways,\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\n multicallData.callbackFunction,\n abi.encode(\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n )\n );\n }\n}\n" + }, + "contracts/wrapper/BytesUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nlibrary BytesUtils {\n /*\n * @dev Returns the keccak-256 hash of a byte range.\n * @param self The byte string to hash.\n * @param offset The position to start hashing at.\n * @param len The number of bytes to hash.\n * @return The hash of the byte range.\n */\n function keccak(\n bytes memory self,\n uint256 offset,\n uint256 len\n ) internal pure returns (bytes32 ret) {\n require(offset + len <= self.length);\n assembly {\n ret := keccak256(add(add(self, 32), offset), len)\n }\n }\n\n /**\n * @dev Returns the ENS namehash of a DNS-encoded name.\n * @param self The DNS-encoded name to hash.\n * @param offset The offset at which to start hashing.\n * @return The namehash of the name.\n */\n function namehash(\n bytes memory self,\n uint256 offset\n ) internal pure returns (bytes32) {\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\n if (labelhash == bytes32(0)) {\n require(offset == self.length - 1, \"namehash: Junk at end of name\");\n return bytes32(0);\n }\n return\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\n }\n\n /**\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\n * @param self The byte string to read a label from.\n * @param idx The index to read a label at.\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\n * @return newIdx The index of the start of the next label.\n */\n function readLabel(\n bytes memory self,\n uint256 idx\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\n require(idx < self.length, \"readLabel: Index out of bounds\");\n uint256 len = uint256(uint8(self[idx]));\n if (len > 0) {\n labelhash = keccak(self, idx + 1, len);\n } else {\n labelhash = bytes32(0);\n }\n newIdx = idx + len + 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/UniversalResolver.json b/deployments/mainnet/UniversalResolver.json index 730e2f1d..9698cf05 100644 --- a/deployments/mainnet/UniversalResolver.json +++ b/deployments/mainnet/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0x8cab227b1162f03b8338331adaad7aadc83b895e", + "address": "0xce01f8eee7E479C928F8919abD53E553a36CeF67", "abi": [ { "inputs": [ @@ -596,48 +596,48 @@ "type": "function" } ], - "transactionHash": "0x89fe62b8d107e87f8065de03c5bdd9f957e411776eff647011131737651d472d", + "transactionHash": "0x8200b7e257fb5bd6d7aec25c5172dd5ddc9830b42b827dcf2db51ec97abc034b", "receipt": { "to": null, - "from": "0x69420f05a11f617b4b74ffe2e04b2d300dfa556f", - "contractAddress": "0x8cab227b1162f03b8338331adaad7aadc83b895e", - "transactionIndex": "0x4d", - "gasUsed": "0x302e90", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000004000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000002", - "blockHash": "0xbf913db8f7c8df11fdc99d2de36800dda5362d16253c8a3409312da54f65951c", - "transactionHash": "0xc8728c67dd0bc1ce47114e8d63a565bb92e45af2cc812bf2c8b9ee59e26f0b5d", + "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", + "contractAddress": "0xce01f8eee7E479C928F8919abD53E553a36CeF67", + "transactionIndex": 75, + "gasUsed": "3139326", + "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020004000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcfa5df46abf1521f68ae72a7f7c4661949f4fb08a3d1296fe8082f6580a414e0", + "transactionHash": "0x8200b7e257fb5bd6d7aec25c5172dd5ddc9830b42b827dcf2db51ec97abc034b", "logs": [ { - "address": "0x8cab227b1162f03b8338331adaad7aadc83b895e", - "blockHash": "0xbf913db8f7c8df11fdc99d2de36800dda5362d16253c8a3409312da54f65951c", - "blockNumber": "0x1214a52", - "data": "0x", - "logIndex": "0x6f", - "removed": false, + "transactionIndex": 75, + "blockNumber": 19258213, + "transactionHash": "0x8200b7e257fb5bd6d7aec25c5172dd5ddc9830b42b827dcf2db51ec97abc034b", + "address": "0xce01f8eee7E479C928F8919abD53E553a36CeF67", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], - "transactionHash": "0xc8728c67dd0bc1ce47114e8d63a565bb92e45af2cc812bf2c8b9ee59e26f0b5d", - "transactionIndex": "0x4d" + "data": "0x", + "logIndex": 312, + "blockHash": "0xcfa5df46abf1521f68ae72a7f7c4661949f4fb08a3d1296fe8082f6580a414e0" } ], - "blockNumber": "0x1214a52", - "cumulativeGasUsed": "0x82275c", - "status": "0x1" + "blockNumber": 19258213, + "cumulativeGasUsed": "13822779", + "status": 1, + "byzantium": true }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", [ - "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" + "https://ccip-v2.ens.xyz" ] ], - "numDeployments": 6, - "solcInputHash": "b8a92c9207ae2a5ea22df4d7303f97f4", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0xcae20ad72181f47dfe7fba7d88e8d902a01576b16e93362878e726989d6cfb4d\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n if (!result.success) {\\n revert ResolverError(result.returnData);\\n }\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = multicallData.data[i];\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0ba4e0ec4c2823f16c5d01402a605999a52a874311568025ba752d2d4db6af1d\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003a9138038062003a918339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516135d2620004bf600039600081816101ea015261150601526135d26000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", + "numDeployments": 7, + "solcInputHash": "49f758ec505ff69b72f3179ac11d7cfc", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n uint256 hexLength = lastIdx - idx;\\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\\n revert(\\\"Invalid string length\\\");\\n }\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0x4a8a9c72d6f3effb80b310faa6dc273e7adbc3b949df9c7a42e290e5b13519f3\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = item;\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2a03a3a94a411b599690e58634c2c5695561cbe4a16fae60cbfefa872a6c2f7b\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003b0f38038062003b0f8339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613650620004bf600039600081816101ea01526114fc01526136506000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -703,7 +703,7 @@ "type": "t_address" }, { - "astId": 1511, + "astId": 1537, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "batchGatewayURLs", "offset": 0, diff --git a/deployments/mainnet/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json b/deployments/mainnet/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json new file mode 100644 index 00000000..51bd8239 --- /dev/null +++ b/deployments/mainnet/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json @@ -0,0 +1,101 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/registry/ENS.sol": { + "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n // Logged when the owner of a node assigns a new owner to a subnode.\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n // Logged when the owner of a node transfers ownership to a new account.\n event Transfer(bytes32 indexed node, address owner);\n\n // Logged when the resolver for a node changes.\n event NewResolver(bytes32 indexed node, address resolver);\n\n // Logged when the TTL of a node changes\n event NewTTL(bytes32 indexed node, uint64 ttl);\n\n // Logged when an operator is added or removed.\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n function setRecord(\n bytes32 node,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner\n ) external returns (bytes32);\n\n function setResolver(bytes32 node, address resolver) external;\n\n function setOwner(bytes32 node, address owner) external;\n\n function setTTL(bytes32 node, uint64 ttl) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function owner(bytes32 node) external view returns (address);\n\n function resolver(bytes32 node) external view returns (address);\n\n function ttl(bytes32 node) external view returns (uint64);\n\n function recordExists(bytes32 node) external view returns (bool);\n\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/resolvers/profiles/IABIResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IABIResolver {\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\n\n /**\n * Returns the ABI associated with an ENS node.\n * Defined in EIP205.\n * @param node The ENS node to query\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\n * @return contentType The content type of the return value\n * @return data The ABI data\n */\n function ABI(\n bytes32 node,\n uint256 contentTypes\n ) external view returns (uint256, bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddressResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the new (multicoin) addr function.\n */\ninterface IAddressResolver {\n event AddressChanged(\n bytes32 indexed node,\n uint256 coinType,\n bytes newAddress\n );\n\n function addr(\n bytes32 node,\n uint256 coinType\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddrResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the legacy (ETH-only) addr function.\n */\ninterface IAddrResolver {\n event AddrChanged(bytes32 indexed node, address a);\n\n /**\n * Returns the address associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated address.\n */\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "contracts/resolvers/profiles/IContentHashResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IContentHashResolver {\n event ContenthashChanged(bytes32 indexed node, bytes hash);\n\n /**\n * Returns the contenthash associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function contenthash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSRecordResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSRecordResolver {\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\n event DNSRecordChanged(\n bytes32 indexed node,\n bytes name,\n uint16 resource,\n bytes record\n );\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\n\n /**\n * Obtain a DNS record.\n * @param node the namehash of the node for which to fetch the record\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\n * @return the DNS record in wire format if present, otherwise empty\n */\n function dnsRecord(\n bytes32 node,\n bytes32 name,\n uint16 resource\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSZoneResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSZoneResolver {\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\n event DNSZonehashChanged(\n bytes32 indexed node,\n bytes lastzonehash,\n bytes zonehash\n );\n\n /**\n * zonehash obtains the hash for the zone.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function zonehash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IExtendedResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n function resolve(\n bytes memory name,\n bytes memory data\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IInterfaceResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IInterfaceResolver {\n event InterfaceChanged(\n bytes32 indexed node,\n bytes4 indexed interfaceID,\n address implementer\n );\n\n /**\n * Returns the address of a contract that implements the specified interface for this name.\n * If an implementer has not been set for this interfaceID and name, the resolver will query\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\n * will be returned.\n * @param node The ENS node to query.\n * @param interfaceID The EIP 165 interface ID to check for.\n * @return The address that implements this interface, or 0 if the interface is unsupported.\n */\n function interfaceImplementer(\n bytes32 node,\n bytes4 interfaceID\n ) external view returns (address);\n}\n" + }, + "contracts/resolvers/profiles/INameResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface INameResolver {\n event NameChanged(bytes32 indexed node, string name);\n\n /**\n * Returns the name associated with an ENS node, for reverse records.\n * Defined in EIP181.\n * @param node The ENS node to query.\n * @return The associated name.\n */\n function name(bytes32 node) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/profiles/IPubkeyResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IPubkeyResolver {\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\n\n /**\n * Returns the SECP256k1 public key associated with an ENS node.\n * Defined in EIP 619.\n * @param node The ENS node to query\n * @return x The X coordinate of the curve point for the public key.\n * @return y The Y coordinate of the curve point for the public key.\n */\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\n}\n" + }, + "contracts/resolvers/profiles/ITextResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface ITextResolver {\n event TextChanged(\n bytes32 indexed node,\n string indexed indexedKey,\n string key,\n string value\n );\n\n /**\n * Returns the text data associated with an ENS node and key.\n * @param node The ENS node to query.\n * @param key The text data key to query.\n * @return The associated text data.\n */\n function text(\n bytes32 node,\n string calldata key\n ) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/Resolver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./profiles/IABIResolver.sol\";\nimport \"./profiles/IAddressResolver.sol\";\nimport \"./profiles/IAddrResolver.sol\";\nimport \"./profiles/IContentHashResolver.sol\";\nimport \"./profiles/IDNSRecordResolver.sol\";\nimport \"./profiles/IDNSZoneResolver.sol\";\nimport \"./profiles/IInterfaceResolver.sol\";\nimport \"./profiles/INameResolver.sol\";\nimport \"./profiles/IPubkeyResolver.sol\";\nimport \"./profiles/ITextResolver.sol\";\nimport \"./profiles/IExtendedResolver.sol\";\n\n/**\n * A generic resolver interface which includes all the functions including the ones deprecated\n */\ninterface Resolver is\n IERC165,\n IABIResolver,\n IAddressResolver,\n IAddrResolver,\n IContentHashResolver,\n IDNSRecordResolver,\n IDNSZoneResolver,\n IInterfaceResolver,\n INameResolver,\n IPubkeyResolver,\n ITextResolver,\n IExtendedResolver\n{\n /* Deprecated events */\n event ContentChanged(bytes32 indexed node, bytes32 hash);\n\n function setApprovalForAll(address, bool) external;\n\n function approve(bytes32 node, address delegate, bool approved) external;\n\n function isApprovedForAll(address account, address operator) external;\n\n function isApprovedFor(\n address owner,\n bytes32 node,\n address delegate\n ) external;\n\n function setABI(\n bytes32 node,\n uint256 contentType,\n bytes calldata data\n ) external;\n\n function setAddr(bytes32 node, address addr) external;\n\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\n\n function setContenthash(bytes32 node, bytes calldata hash) external;\n\n function setDnsrr(bytes32 node, bytes calldata data) external;\n\n function setName(bytes32 node, string calldata _name) external;\n\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\n\n function setText(\n bytes32 node,\n string calldata key,\n string calldata value\n ) external;\n\n function setInterface(\n bytes32 node,\n bytes4 interfaceID,\n address implementer\n ) external;\n\n function multicall(\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n function multicallWithNodeCheck(\n bytes32 nodehash,\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n /* Deprecated functions */\n function content(bytes32 node) external view returns (bytes32);\n\n function multihash(bytes32 node) external view returns (bytes memory);\n\n function setContent(bytes32 node, bytes32 hash) external;\n\n function setMultihash(bytes32 node, bytes calldata hash) external;\n}\n" + }, + "contracts/utils/HexUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nlibrary HexUtils {\n /**\n * @dev Attempts to parse bytes32 from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexStringToBytes32(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (bytes32 r, bool valid) {\n uint256 hexLength = lastIdx - idx;\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\n revert(\"Invalid string length\");\n }\n valid = true;\n assembly {\n // check that the index to read to is not past the end of the string\n if gt(lastIdx, mload(str)) {\n revert(0, 0)\n }\n\n function getHex(c) -> ascii {\n // chars 48-57: 0-9\n if and(gt(c, 47), lt(c, 58)) {\n ascii := sub(c, 48)\n leave\n }\n // chars 65-70: A-F\n if and(gt(c, 64), lt(c, 71)) {\n ascii := add(sub(c, 65), 10)\n leave\n }\n // chars 97-102: a-f\n if and(gt(c, 96), lt(c, 103)) {\n ascii := add(sub(c, 97), 10)\n leave\n }\n // invalid char\n ascii := 0xff\n }\n\n let ptr := add(str, 32)\n for {\n let i := idx\n } lt(i, lastIdx) {\n i := add(i, 2)\n } {\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\n // if either byte is invalid, set invalid and break loop\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\n valid := false\n break\n }\n let combined := or(shl(4, byte1), byte2)\n r := or(shl(8, r), combined)\n }\n }\n }\n\n /**\n * @dev Attempts to parse an address from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexToAddress(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (address, bool) {\n if (lastIdx - idx < 40) return (address(0x0), false);\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\n return (address(uint160(uint256(r))), valid);\n }\n}\n" + }, + "contracts/utils/LowLevelCallUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nlibrary LowLevelCallUtils {\n using Address for address;\n\n /**\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data\n ) internal view returns (bool success) {\n return functionStaticCall(target, data, gasleft());\n }\n\n /**\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @param gasLimit The gas limit to use for the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n uint256 gasLimit\n ) internal view returns (bool success) {\n require(\n target.isContract(),\n \"LowLevelCallUtils: static call to non-contract\"\n );\n assembly {\n success := staticcall(\n gasLimit,\n target,\n add(data, 32),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n /**\n * @dev Returns the size of the return data of the most recent external call.\n */\n function returnDataSize() internal pure returns (uint256 len) {\n assembly {\n len := returndatasize()\n }\n }\n\n /**\n * @dev Reads return data from the most recent external call.\n * @param offset Offset into the return data.\n * @param length Number of bytes to return.\n */\n function readReturnData(\n uint256 offset,\n uint256 length\n ) internal pure returns (bytes memory data) {\n data = new bytes(length);\n assembly {\n returndatacopy(add(data, 32), offset, length)\n }\n }\n\n /**\n * @dev Reverts with the return data from the most recent external call.\n */\n function propagateRevert() internal pure {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n}\n" + }, + "contracts/utils/NameEncoder.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\n\nlibrary NameEncoder {\n using BytesUtils for bytes;\n\n function dnsEncodeName(\n string memory name\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\n uint8 labelLength = 0;\n bytes memory bytesName = bytes(name);\n uint256 length = bytesName.length;\n dnsName = new bytes(length + 2);\n node = 0;\n if (length == 0) {\n dnsName[0] = 0;\n return (dnsName, node);\n }\n\n // use unchecked to save gas since we check for an underflow\n // and we check for the length before the loop\n unchecked {\n for (uint256 i = length - 1; i >= 0; i--) {\n if (bytesName[i] == \".\") {\n dnsName[i + 1] = bytes1(labelLength);\n node = keccak256(\n abi.encodePacked(\n node,\n bytesName.keccak(i + 1, labelLength)\n )\n );\n labelLength = 0;\n } else {\n labelLength += 1;\n dnsName[i + 1] = bytesName[i];\n }\n if (i == 0) {\n break;\n }\n }\n }\n\n node = keccak256(\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\n );\n\n dnsName[0] = bytes1(labelLength);\n return (dnsName, node);\n }\n}\n" + }, + "contracts/utils/UniversalResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17 <0.9.0;\n\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {LowLevelCallUtils} from \"./LowLevelCallUtils.sol\";\nimport {ENS} from \"../registry/ENS.sol\";\nimport {IExtendedResolver} from \"../resolvers/profiles/IExtendedResolver.sol\";\nimport {Resolver, INameResolver, IAddrResolver} from \"../resolvers/Resolver.sol\";\nimport {NameEncoder} from \"./NameEncoder.sol\";\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\nimport {HexUtils} from \"./HexUtils.sol\";\n\nerror OffchainLookup(\n address sender,\n string[] urls,\n bytes callData,\n bytes4 callbackFunction,\n bytes extraData\n);\n\nerror ResolverNotFound();\n\nerror ResolverWildcardNotSupported();\n\nerror ResolverNotContract();\n\nerror ResolverError(bytes returnData);\n\nerror HttpError(HttpErrorItem[] errors);\n\nstruct HttpErrorItem {\n uint16 status;\n string message;\n}\n\nstruct MulticallData {\n bytes name;\n bytes[] data;\n string[] gateways;\n bytes4 callbackFunction;\n bool isWildcard;\n address resolver;\n bytes metaData;\n bool[] failures;\n}\n\nstruct MulticallChecks {\n bool isCallback;\n bool hasExtendedResolver;\n}\n\nstruct OffchainLookupCallData {\n address sender;\n string[] urls;\n bytes callData;\n}\n\nstruct OffchainLookupExtraData {\n bytes4 callbackFunction;\n bytes data;\n}\n\nstruct Result {\n bool success;\n bytes returnData;\n}\n\ninterface BatchGateway {\n function query(\n OffchainLookupCallData[] memory data\n ) external returns (bool[] memory failures, bytes[] memory responses);\n}\n\n/**\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\n * making it possible to make a single smart contract call to resolve an ENS name.\n */\ncontract UniversalResolver is ERC165, Ownable {\n using Address for address;\n using NameEncoder for string;\n using BytesUtils for bytes;\n using HexUtils for bytes;\n\n string[] public batchGatewayURLs;\n ENS public immutable registry;\n\n constructor(address _registry, string[] memory _urls) {\n registry = ENS(_registry);\n batchGatewayURLs = _urls;\n }\n\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\n batchGatewayURLs = _urls;\n }\n\n /**\n * @dev Performs ENS name resolution for the supplied name and resolution data.\n * @param name The name to resolve, in normalised and DNS-encoded form.\n * @param data The resolution data, as specified in ENSIP-10.\n * @return The result of resolving the name.\n */\n function resolve(\n bytes calldata name,\n bytes memory data\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n batchGatewayURLs,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data\n ) external view returns (Result[] memory, address) {\n return resolve(name, data, batchGatewayURLs);\n }\n\n function resolve(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n gateways,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways\n ) public view returns (Result[] memory, address) {\n return\n _resolve(name, data, gateways, this.resolveCallback.selector, \"\");\n }\n\n function _resolveSingle(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) public view returns (bytes memory, address) {\n bytes[] memory dataArr = new bytes[](1);\n dataArr[0] = data;\n (Result[] memory results, address resolver) = _resolve(\n name,\n dataArr,\n gateways,\n callbackFunction,\n metaData\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function _resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) internal view returns (Result[] memory results, address resolverAddress) {\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\n resolverAddress = address(resolver);\n if (resolverAddress == address(0)) {\n revert ResolverNotFound();\n }\n\n if (!resolverAddress.isContract()) {\n revert ResolverNotContract();\n }\n\n bool isWildcard = finalOffset != 0;\n\n results = _multicall(\n MulticallData(\n name,\n data,\n gateways,\n callbackFunction,\n isWildcard,\n resolverAddress,\n metaData,\n new bool[](data.length)\n )\n );\n }\n\n function reverse(\n bytes calldata reverseName\n ) external view returns (string memory, address, address, address) {\n return reverse(reverseName, batchGatewayURLs);\n }\n\n /**\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\n */\n function reverse(\n bytes calldata reverseName,\n string[] memory gateways\n ) public view returns (string memory, address, address, address) {\n bytes memory encodedCall = abi.encodeCall(\n INameResolver.name,\n reverseName.namehash(0)\n );\n (\n bytes memory reverseResolvedData,\n address reverseResolverAddress\n ) = _resolveSingle(\n reverseName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n \"\"\n );\n\n return\n getForwardDataFromReverse(\n reverseResolvedData,\n reverseResolverAddress,\n gateways\n );\n }\n\n function getForwardDataFromReverse(\n bytes memory resolvedReverseData,\n address reverseResolverAddress,\n string[] memory gateways\n ) internal view returns (string memory, address, address, address) {\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\n\n (bytes memory encodedName, bytes32 namehash) = resolvedName\n .dnsEncodeName();\n\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\n bytes memory metaData = abi.encode(\n resolvedName,\n reverseResolverAddress\n );\n (bytes memory resolvedData, address resolverAddress) = this\n ._resolveSingle(\n encodedName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n metaData\n );\n\n address resolvedAddress = abi.decode(resolvedData, (address));\n\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n function resolveSingleCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (bytes memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveSingleCallback.selector\n );\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function resolveCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (Result[] memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveCallback.selector\n );\n return (results, resolver);\n }\n\n function reverseCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (string memory, address, address, address) {\n (\n Result[] memory results,\n address resolverAddress,\n string[] memory gateways,\n bytes memory metaData\n ) = _resolveCallback(\n response,\n extraData,\n this.reverseCallback.selector\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n if (metaData.length > 0) {\n (string memory resolvedName, address reverseResolverAddress) = abi\n .decode(metaData, (string, address));\n address resolvedAddress = abi.decode(result.returnData, (address));\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n return\n getForwardDataFromReverse(\n result.returnData,\n resolverAddress,\n gateways\n );\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override returns (bool) {\n return\n interfaceId == type(IExtendedResolver).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n function _resolveCallback(\n bytes calldata response,\n bytes calldata extraData,\n bytes4 callbackFunction\n )\n internal\n view\n returns (Result[] memory, address, string[] memory, bytes memory)\n {\n MulticallData memory multicallData;\n multicallData.callbackFunction = callbackFunction;\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\n response,\n (bool[], bytes[])\n );\n OffchainLookupExtraData[] memory extraDatas;\n (\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n ) = abi.decode(\n extraData,\n (bool, address, string[], bytes, OffchainLookupExtraData[])\n );\n require(responses.length <= extraDatas.length);\n multicallData.data = new bytes[](extraDatas.length);\n multicallData.failures = new bool[](extraDatas.length);\n uint256 offchainCount = 0;\n for (uint256 i = 0; i < extraDatas.length; i++) {\n if (extraDatas[i].callbackFunction == bytes4(0)) {\n // This call did not require an offchain lookup; use the previous input data.\n multicallData.data[i] = extraDatas[i].data;\n } else {\n if (failures[offchainCount]) {\n multicallData.failures[i] = true;\n multicallData.data[i] = responses[offchainCount];\n } else {\n multicallData.data[i] = abi.encodeWithSelector(\n extraDatas[i].callbackFunction,\n responses[offchainCount],\n extraDatas[i].data\n );\n }\n offchainCount = offchainCount + 1;\n }\n }\n\n return (\n _multicall(multicallData),\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData\n );\n }\n\n /**\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\n * the error with the data necessary to continue the request where it left off.\n * @param target The address to call.\n * @param data The data to call `target` with.\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\n * @return result Whether the call succeeded.\n */\n function callWithOffchainLookupPropagation(\n address target,\n bytes memory data,\n bool isSafe\n )\n internal\n view\n returns (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool result\n )\n {\n if (isSafe) {\n result = LowLevelCallUtils.functionStaticCall(target, data);\n } else {\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\n }\n uint256 size = LowLevelCallUtils.returnDataSize();\n\n if (result) {\n return (\n false,\n LowLevelCallUtils.readReturnData(0, size),\n extraData,\n true\n );\n }\n\n // Failure\n if (size >= 4) {\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\n // Offchain lookup. Decode the revert message and create our own that nests it.\n bytes memory revertData = LowLevelCallUtils.readReturnData(\n 4,\n size - 4\n );\n if (bytes4(errorId) == OffchainLookup.selector) {\n (\n address wrappedSender,\n string[] memory wrappedUrls,\n bytes memory wrappedCallData,\n bytes4 wrappedCallbackFunction,\n bytes memory wrappedExtraData\n ) = abi.decode(\n revertData,\n (address, string[], bytes, bytes4, bytes)\n );\n if (wrappedSender == target) {\n returnData = abi.encode(\n OffchainLookupCallData(\n wrappedSender,\n wrappedUrls,\n wrappedCallData\n )\n );\n extraData = OffchainLookupExtraData(\n wrappedCallbackFunction,\n wrappedExtraData\n );\n return (true, returnData, extraData, false);\n }\n } else {\n returnData = bytes.concat(errorId, revertData);\n return (false, returnData, extraData, false);\n }\n }\n }\n\n /**\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\n * removing labels until it finds a result.\n * @param name The name to resolve, in DNS-encoded and normalised form.\n * @return resolver The Resolver responsible for this name.\n * @return namehash The namehash of the full name.\n * @return finalOffset The offset of the first label with a resolver.\n */\n function findResolver(\n bytes calldata name\n ) public view returns (Resolver, bytes32, uint256) {\n (\n address resolver,\n bytes32 namehash,\n uint256 finalOffset\n ) = findResolver(name, 0);\n return (Resolver(resolver), namehash, finalOffset);\n }\n\n function findResolver(\n bytes calldata name,\n uint256 offset\n ) internal view returns (address, bytes32, uint256) {\n uint256 labelLength = uint256(uint8(name[offset]));\n if (labelLength == 0) {\n return (address(0), bytes32(0), offset);\n }\n uint256 nextLabel = offset + labelLength + 1;\n bytes32 labelHash;\n if (\n labelLength == 66 &&\n // 0x5b == '['\n name[offset + 1] == 0x5b &&\n // 0x5d == ']'\n name[nextLabel - 1] == 0x5d\n ) {\n // Encrypted label\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\n .hexStringToBytes32(0, 64);\n } else {\n labelHash = keccak256(name[offset + 1:nextLabel]);\n }\n (\n address parentresolver,\n bytes32 parentnode,\n uint256 parentoffset\n ) = findResolver(name, nextLabel);\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\n address resolver = registry.resolver(node);\n if (resolver != address(0)) {\n return (resolver, node, offset);\n }\n return (parentresolver, node, parentoffset);\n }\n\n function _checkInterface(\n address resolver,\n bytes4 interfaceId\n ) internal view returns (bool) {\n try\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\n returns (bool supported) {\n return supported;\n } catch {\n return false;\n }\n }\n\n function _checkSafetyAndItem(\n bytes memory name,\n bytes memory item,\n address resolver,\n MulticallChecks memory multicallChecks\n ) internal view returns (bool, bytes memory) {\n if (!multicallChecks.isCallback) {\n if (multicallChecks.hasExtendedResolver) {\n return (\n true,\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\n );\n }\n return (_checkInterface(resolver, bytes4(item)), item);\n }\n return (true, item);\n }\n\n function _checkMulticall(\n MulticallData memory multicallData\n ) internal view returns (MulticallChecks memory) {\n bool isCallback = multicallData.name.length == 0;\n bool hasExtendedResolver = _checkInterface(\n multicallData.resolver,\n type(IExtendedResolver).interfaceId\n );\n\n if (multicallData.isWildcard && !hasExtendedResolver) {\n revert ResolverWildcardNotSupported();\n }\n\n return MulticallChecks(isCallback, hasExtendedResolver);\n }\n\n function _checkResolveSingle(Result memory result) internal pure {\n if (!result.success) {\n if (bytes4(result.returnData) == HttpError.selector) {\n bytes memory returnData = result.returnData;\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n revert ResolverError(result.returnData);\n }\n }\n\n function _multicall(\n MulticallData memory multicallData\n ) internal view returns (Result[] memory results) {\n uint256 length = multicallData.data.length;\n uint256 offchainCount = 0;\n OffchainLookupCallData[]\n memory callDatas = new OffchainLookupCallData[](length);\n OffchainLookupExtraData[]\n memory extraDatas = new OffchainLookupExtraData[](length);\n results = new Result[](length);\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\n\n for (uint256 i = 0; i < length; i++) {\n bytes memory item = multicallData.data[i];\n bool failure = multicallData.failures[i];\n\n if (failure) {\n results[i] = Result(false, item);\n continue;\n }\n\n bool isSafe = false;\n (isSafe, item) = _checkSafetyAndItem(\n multicallData.name,\n item,\n multicallData.resolver,\n multicallChecks\n );\n\n (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool success\n ) = callWithOffchainLookupPropagation(\n multicallData.resolver,\n item,\n isSafe\n );\n\n if (offchain) {\n callDatas[offchainCount] = abi.decode(\n returnData,\n (OffchainLookupCallData)\n );\n extraDatas[i] = extraData;\n offchainCount += 1;\n continue;\n }\n\n if (success && multicallChecks.hasExtendedResolver) {\n // if this is a successful resolve() call, unwrap the result\n returnData = abi.decode(returnData, (bytes));\n }\n results[i] = Result(success, returnData);\n extraDatas[i].data = item;\n }\n\n if (offchainCount == 0) {\n return results;\n }\n\n // Trim callDatas if offchain data exists\n assembly {\n mstore(callDatas, offchainCount)\n }\n\n revert OffchainLookup(\n address(this),\n multicallData.gateways,\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\n multicallData.callbackFunction,\n abi.encode(\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n )\n );\n }\n}\n" + }, + "contracts/wrapper/BytesUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nlibrary BytesUtils {\n /*\n * @dev Returns the keccak-256 hash of a byte range.\n * @param self The byte string to hash.\n * @param offset The position to start hashing at.\n * @param len The number of bytes to hash.\n * @return The hash of the byte range.\n */\n function keccak(\n bytes memory self,\n uint256 offset,\n uint256 len\n ) internal pure returns (bytes32 ret) {\n require(offset + len <= self.length);\n assembly {\n ret := keccak256(add(add(self, 32), offset), len)\n }\n }\n\n /**\n * @dev Returns the ENS namehash of a DNS-encoded name.\n * @param self The DNS-encoded name to hash.\n * @param offset The offset at which to start hashing.\n * @return The namehash of the name.\n */\n function namehash(\n bytes memory self,\n uint256 offset\n ) internal pure returns (bytes32) {\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\n if (labelhash == bytes32(0)) {\n require(offset == self.length - 1, \"namehash: Junk at end of name\");\n return bytes32(0);\n }\n return\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\n }\n\n /**\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\n * @param self The byte string to read a label from.\n * @param idx The index to read a label at.\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\n * @return newIdx The index of the start of the next label.\n */\n function readLabel(\n bytes memory self,\n uint256 idx\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\n require(idx < self.length, \"readLabel: Index out of bounds\");\n uint256 len = uint256(uint8(self[idx]));\n if (len > 0) {\n labelhash = keccak(self, idx + 1, len);\n } else {\n labelhash = bytes32(0);\n }\n newIdx = idx + len + 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/sepolia/UniversalResolver.json b/deployments/sepolia/UniversalResolver.json index 2167ac81..06825a9c 100644 --- a/deployments/sepolia/UniversalResolver.json +++ b/deployments/sepolia/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", + "address": "0xc8af999e38273d658be1b921b88a9ddf005769cc", "abi": [ { "inputs": [ @@ -596,48 +596,48 @@ "type": "function" } ], - "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", + "transactionHash": "0x3bb62376ac60bc8e9138c5861c6a62ba0b6b9324040c08c44bcb5250f123e501", "receipt": { "to": null, - "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", - "contractAddress": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", - "transactionIndex": 107, - "gasUsed": "3157648", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000004000000000000000000000000000000000000", - "blockHash": "0x338a8b517341cac3213d0605f18628405926d8601e031419a3cb6163a39b19e7", - "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", + "from": "0x69420f05a11f617b4b74ffe2e04b2d300dfa556f", + "contractAddress": "0xc8af999e38273d658be1b921b88a9ddf005769cc", + "transactionIndex": "0x66", + "gasUsed": "0x2fe6fe", + "logsBloom": "0x00000000010000000400000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x25e7f3d78538093ee023c6a495b423671065539c55907f9f9d91791f1765af2e", + "transactionHash": "0x7e9dca6d913dc0b14b42df843fd75c420ff1b73bfb9941a7eb92b40e6881c006", "logs": [ { - "transactionIndex": 107, - "blockNumber": 5043334, - "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", - "address": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", + "address": "0xc8af999e38273d658be1b921b88a9ddf005769cc", + "blockHash": "0x25e7f3d78538093ee023c6a495b423671065539c55907f9f9d91791f1765af2e", + "blockNumber": "0x5121d8", + "data": "0x", + "logIndex": "0x9a", + "removed": false, "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], - "data": "0x", - "logIndex": 197, - "blockHash": "0x338a8b517341cac3213d0605f18628405926d8601e031419a3cb6163a39b19e7" + "transactionHash": "0x7e9dca6d913dc0b14b42df843fd75c420ff1b73bfb9941a7eb92b40e6881c006", + "transactionIndex": "0x66" } ], - "blockNumber": 5043334, - "cumulativeGasUsed": "16762495", - "status": 1, - "byzantium": true + "blockNumber": "0x5121d8", + "cumulativeGasUsed": "0xcc252a", + "status": "0x1" }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", [ - "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" + "https://ccip-v2.ens.xyz" ] ], - "numDeployments": 4, - "solcInputHash": "b8a92c9207ae2a5ea22df4d7303f97f4", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0xcae20ad72181f47dfe7fba7d88e8d902a01576b16e93362878e726989d6cfb4d\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n if (!result.success) {\\n revert ResolverError(result.returnData);\\n }\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = multicallData.data[i];\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x0ba4e0ec4c2823f16c5d01402a605999a52a874311568025ba752d2d4db6af1d\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003a9138038062003a918339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516135d2620004bf600039600081816101ea015261150601526135d26000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612377565b610325565b60405190151581526020015b60405180910390f35b610176610171366004612597565b61035c565b60405161015a929190612675565b610197610192366004612720565b610392565b60405161015a929190612789565b6101b86101b3366004612812565b61047f565b60405161015a949392919061287e565b6101d061056f565b005b6101976101e03660046128ba565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612919565b6105ab565b6101d06102563660046129df565b61064e565b610176610269366004612a1c565b61066d565b61028161027c366004612a7b565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612abd565b61078c565b60405161015a9190612ad6565b6101b86102d4366004612ae9565b610838565b6101976102e7366004612812565b61092a565b6101766102fa366004612812565b61096e565b6101b861030d366004612a7b565b6109e0565b6101d0610320366004612b5d565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b7a565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b7a565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bb4565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c0f565b91509150600083602001518060200190518101906105319190612c61565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bb4565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bb4565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122a4565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b7a565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b888860006112ff565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b7a565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b7a565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115ad9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bb4565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b7a565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b7a565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c8c565b90925090506060610bf98a8c018c612d44565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123dd565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123dd565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bb4565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bb4565b60200260200101516020015186602001518281518110610d4257610d42612bb4565b6020026020010181905250610ea5565b848281518110610d6457610d64612bb4565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bb4565b602002602001019015159081151581525050838281518110610dad57610dad612bb4565b602002602001015186602001518281518110610dcb57610dcb612bb4565b6020026020010181905250610e97565b828181518110610ded57610ded612bb4565b602002602001015160000151848381518110610e0b57610e0b612bb4565b6020026020010151848381518110610e2557610e25612bb4565b602002602001015160200151604051602401610e42929190612ec8565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bb4565b60200260200101819052505b610ea2826001612f0c565b91505b80610eaf81612f1f565b915050610cd3565b50610ec18561166c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f38565b9050600080610f1383611a77565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612675565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fc2565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c0f565b915091506000828060200190518101906110349190612c61565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123dd565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261166c565b9450505050965096945050505050565b8051610b605760208101517fca7a4e7500000000000000000000000000000000000000000000000000000000906112c39061302b565b6001600160e01b031916036112e057602080820151805190918201fd5b8060200151604051634ae063a960e11b81526004016104ec9190612ad6565b60008060008086868681811061131757611317612bb4565b919091013560f81c915050600081900361133b5750600092508291508390506115a4565b60006113478287612f0c565b611352906001612f0c565b905060008260421480156113985750888861136e896001612f0c565b81811061137d5761137d612bb4565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113d6575088886113ac600185613063565b8181106113bb576113bb612bb4565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561144e57611446600060408b8b6113ef8c6002612f0c565b906113fb600189613063565b9261140893929190613076565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611ca09050565b509050611480565b888861145b896001612f0c565b61146792859290613076565b6040516114759291906130a0565b604051809103902090505b60008060006114908c8c876112ff565b925092509250600082856040516020016114b4929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561154d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115719190612c61565b90506001600160a01b0381161561159557995097508996506115a495505050505050565b50929850919650909450505050505b93509350939050565b60008060006115bc8585611d71565b90925090508161162e57600185516115d49190613063565b84146116225760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61163885826115ad565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff811115611691576116916123dd565b6040519080825280602002602001820160405280156116ef57816020015b6116dc604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116af5790505b50905060008367ffffffffffffffff81111561170d5761170d6123dd565b60405190808252806020026020018201604052801561175357816020015b60408051808201909152600081526060602082015281526020019060019003908161172b5790505b5090508367ffffffffffffffff81111561176f5761176f6123dd565b6040519080825280602002602001820160405280156117b557816020015b60408051808201909152600081526060602082015281526020019060019003908161178d5790505b50945060006117c387611e28565b905060005b858110156119b6576000886020015182815181106117e8576117e8612bb4565b6020026020010151905060008960e00151838151811061180a5761180a612bb4565b6020026020010151905080156118565760405180604001604052806000151581526020018381525089848151811061184457611844612bb4565b602002602001018190525050506119a4565b600061186c8b60000151848d60a0015188611ebf565b80945081925050506000806000806118898f60a001518887611f47565b935093509350935083156118ff57828060200190518101906118ab9190613130565b8b8d815181106118bd576118bd612bb4565b6020026020010181905250818a89815181106118db576118db612bb4565b60209081029190910101526118f160018d612f0c565b9b50505050505050506119a4565b80801561190d575088602001515b1561192957828060200190518101906119269190612f38565b92505b60405180604001604052808215158152602001848152508e898151811061195257611952612bb4565b60200260200101819052508e60200151888151811061197357611973612bb4565b60200260200101518a898151811061198d5761198d612bb4565b602002602001015160200181905250505050505050505b806119ae81612f1f565b9150506117c8565b50836000036119c9575050505050919050565b83835230876040015163a780bab660e01b856040516024016119eb919061322b565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a4c95949392919061328d565b60408051601f1981840301815290829052630556f18360e41b82526104ec959493929160040161334a565b805160609060009081908490611a8e816002612f0c565b67ffffffffffffffff811115611aa657611aa66123dd565b6040519080825280601f01601f191660200182016040528015611ad0576020820181803683370190505b50945060009350808403611b1557600060f81b85600081518110611af657611af6612bb4565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b2d57611b2d612bb4565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bef578360f81b868260010181518110611b9357611b93612bb4565b60200101906001600160f81b031916908160001a90535084611bbc846001840160ff88166120ff565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c3f565b600184019350828181518110611c0757611c07612bb4565b602001015160f81c60f81b868260010181518110611c2757611c27612bb4565b60200101906001600160f81b031916908160001a9053505b8015611c4e5760001901611b1b565b5083611c5f83600060ff87166120ff565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611af657611af6612bb4565b8251600090600190831115611cb457600080fd5b611d05565b6000603a8210602f83111615611cd15750602f190190565b60478210604083111615611ce757506036190190565b60678210606083111615611cfd57506056190190565b5060ff919050565b60208501845b84811015611d6757611d228183015160001a611cb9565b611d346001830184015160001a611cb9565b60ff811460ff83141715611d4d57600094505050611d67565b60049190911b1760089490941b9390931792600201611d0b565b5050935093915050565b60008083518310611dc45760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611dd857611dd8612bb4565b016020015160f81c90508015611e0457611dfd85611df7866001612f0c565b836120ff565b9250611e09565b600092505b611e138185612f0c565b611e1e906001612f0c565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e5b90639061b92360e01b612123565b905083608001518015611e6c575080155b15611ea3576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f3b57826020015115611f1f5760018686604051602401611eeb929190612ec8565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f3184611f2c8761302b565b612123565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f7a57611f7387876121a8565b9050611f8a565b611f87878761c3506121bc565b90505b3d8115611fae576000611f9e60008361224f565b9095509350600191506109219050565b600481106120f5576000611fc46000600461224f565b90506000611fdc6004611fd78186613063565b61224f565b9050630556f18360e41b611fef8361302b565b6001600160e01b031916036120bd5760008060008060008580602001905181019061201a919061337e565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120b3576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001612071919061342e565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b50505050506120f2565b81816040516020016120d0929190613441565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061210e8385612f0c565b111561211957600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612195575060408051601f3d908101601f1916820190925261219291810190613470565b60015b6121a157506000610356565b9050610356565b60006121b583835a6121bc565b9392505050565b60006001600160a01b0384163b61223b5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561226a5761226a6123dd565b6040519080825280601f01601f191660200182016040528015612294576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122ea579160200282015b828111156122ea57825182906122da90826134dc565b50916020019190600101906122c4565b506122f69291506122fa565b5090565b808211156122f657600061230e8282612317565b506001016122fa565b50805461232390612b7a565b6000825580601f10612333575050565b601f016020900490600052602060002090810190610b6091905b808211156122f6576000815560010161234d565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561238957600080fd5b81356121b581612361565b60008083601f8401126123a657600080fd5b50813567ffffffffffffffff8111156123be57600080fd5b6020830191508360208285010111156123d657600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612416576124166123dd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612445576124456123dd565b604052919050565b600067ffffffffffffffff821115612467576124676123dd565b50601f01601f191660200190565b60006124886124838461244d565b61241c565b905082815283838301111561249c57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124c457600080fd5b6121b583833560208501612475565b600067ffffffffffffffff8211156124ed576124ed6123dd565b5060051b60200190565b600082601f83011261250857600080fd5b81356020612518612483836124d3565b82815260059290921b8401810191818101908684111561253757600080fd5b8286015b8481101561258c57803567ffffffffffffffff81111561255b5760008081fd5b8701603f8101891361256d5760008081fd5b61257e898683013560408401612475565b84525091830191830161253b565b509695505050505050565b600080600080606085870312156125ad57600080fd5b843567ffffffffffffffff808211156125c557600080fd5b6125d188838901612394565b909650945060208701359150808211156125ea57600080fd5b6125f6888389016124b3565b9350604087013591508082111561260c57600080fd5b50612619878288016124f7565b91505092959194509250565b60005b83811015612640578181015183820152602001612628565b50506000910152565b60008151808452612661816020860160208601612625565b601f01601f19169290920160200192915050565b6040815260006126886040830185612649565b90506001600160a01b03831660208301529392505050565b600082601f8301126126b157600080fd5b813560206126c1612483836124d3565b82815260059290921b840181019181810190868411156126e057600080fd5b8286015b8481101561258c57803567ffffffffffffffff8111156127045760008081fd5b6127128986838b01016124b3565b8452509183019183016126e4565b60008060006040848603121561273557600080fd5b833567ffffffffffffffff8082111561274d57600080fd5b61275987838801612394565b9095509350602086013591508082111561277257600080fd5b5061277f868287016126a0565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b838110156127f357888603605f1901855281518051151587528301518387018890526127e088880182612649565b96505093820193908201906001016127b2565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561282857600080fd5b843567ffffffffffffffff8082111561284057600080fd5b61284c88838901612394565b9096509450602087013591508082111561286557600080fd5b5061287287828801612394565b95989497509550505050565b6080815260006128916080830187612649565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128d057600080fd5b843567ffffffffffffffff808211156128e857600080fd5b6128f488838901612394565b9096509450602087013591508082111561290d57600080fd5b6125f6888389016126a0565b60008060008060008060a0878903121561293257600080fd5b863567ffffffffffffffff8082111561294a57600080fd5b6129568a838b01612394565b9098509650602089013591508082111561296f57600080fd5b61297b8a838b016124b3565b9550604089013591508082111561299157600080fd5b61299d8a838b016124f7565b9450606089013591506129af82612361565b909250608088013590808211156129c557600080fd5b506129d289828a016124b3565b9150509295509295509295565b6000602082840312156129f157600080fd5b813567ffffffffffffffff811115612a0857600080fd5b612a14848285016124f7565b949350505050565b600080600060408486031215612a3157600080fd5b833567ffffffffffffffff80821115612a4957600080fd5b612a5587838801612394565b90955093506020860135915080821115612a6e57600080fd5b5061277f868287016124b3565b60008060208385031215612a8e57600080fd5b823567ffffffffffffffff811115612aa557600080fd5b612ab185828601612394565b90969095509350505050565b600060208284031215612acf57600080fd5b5035919050565b6020815260006121b56020830184612649565b600080600060408486031215612afe57600080fd5b833567ffffffffffffffff80821115612b1657600080fd5b612b2287838801612394565b90955093506020860135915080821115612b3b57600080fd5b5061277f868287016124f7565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b6f57600080fd5b81356121b581612b48565b600181811c90821680612b8e57607f821691505b602082108103612bae57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bdb57600080fd5b8151612be96124838261244d565b818152846020838601011115612bfe57600080fd5b612a14826020830160208701612625565b60008060408385031215612c2257600080fd5b825167ffffffffffffffff811115612c3957600080fd5b612c4585828601612bca565b9250506020830151612c5681612b48565b809150509250929050565b600060208284031215612c7357600080fd5b81516121b581612b48565b8015158114610b6057600080fd5b60008060408385031215612c9f57600080fd5b823567ffffffffffffffff80821115612cb757600080fd5b818501915085601f830112612ccb57600080fd5b81356020612cdb612483836124d3565b82815260059290921b84018101918181019089841115612cfa57600080fd5b948201945b83861015612d21578535612d1281612c7e565b82529482019490820190612cff565b96505086013592505080821115612d3757600080fd5b50611e1e858286016126a0565b600080600080600060a08688031215612d5c57600080fd5b612d668635612c7e565b85359450612d776020870135612b48565b6020860135935067ffffffffffffffff8060408801351115612d9857600080fd5b612da888604089013589016124f7565b93508060608801351115612dbb57600080fd5b612dcb88606089013589016124b3565b92508060808801351115612dde57600080fd5b6080870135870188601f820112612df457600080fd5b612e0161248382356124d3565b81358082526020808301929160051b8401018b1015612e1f57600080fd5b602083015b6020843560051b850101811015612eb6578481351115612e4357600080fd5b803584016040818e03601f19011215612e5b57600080fd5b612e636123f3565b612e706020830135612361565b602082013581528660408301351115612e8857600080fd5b612e9b8e602060408501358501016124b3565b60208201528085525050602083019250602081019050612e24565b50809450505050509295509295909350565b604081526000612edb6040830185612649565b8281036020840152612eed8185612649565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612ef6565b600060018201612f3157612f31612ef6565b5060010190565b600060208284031215612f4a57600080fd5b815167ffffffffffffffff811115612f6157600080fd5b612a1484828501612bca565b600081518084526020808501808196508360051b8101915082860160005b85811015612fb5578284038952612fa3848351612649565b98850198935090840190600101612f8b565b5091979650505050505050565b60a081526000612fd560a0830188612649565b8281036020840152612fe78188612649565b90508281036040840152612ffb8187612f6d565b90506001600160e01b031985166060840152828103608084015261301f8185612649565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561305b5780818460040360031b1b83161693505b505050919050565b8181038181111561035657610356612ef6565b6000808585111561308657600080fd5b8386111561309357600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130c157600080fd5b815160206130d1612483836124d3565b82815260059290921b840181019181810190868411156130f057600080fd5b8286015b8481101561258c57805167ffffffffffffffff8111156131145760008081fd5b6131228986838b0101612bca565b8452509183019183016130f4565b60006020828403121561314257600080fd5b815167ffffffffffffffff8082111561315a57600080fd5b908301906060828603121561316e57600080fd5b604051606081018181108382111715613189576131896123dd565b604052825161319781612b48565b81526020830151828111156131ab57600080fd5b6131b7878286016130b0565b6020830152506040830151828111156131cf57600080fd5b6131db87828601612bca565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526132126060850182612f6d565b905060408301518482036040860152612eed8282612649565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561328057603f1988860301845261326e8583516131ea565b94509285019290850190600101613252565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a0818501526132b960a0850188612f6d565b84810360608601526132cb8188612649565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561333757858303601f19018552815180516001600160e01b031916845288015188840188905261332488850182612649565b95890195935050908701906001016132ee565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061336c60a0830187612f6d565b8281036040840152612ffb8187612649565b600080600080600060a0868803121561339657600080fd5b85516133a181612b48565b602087015190955067ffffffffffffffff808211156133bf57600080fd5b6133cb89838a016130b0565b955060408801519150808211156133e157600080fd5b6133ed89838a01612bca565b9450606088015191506133ff82612361565b60808801519193508082111561341457600080fd5b5061342188828901612bca565b9150509295509295909350565b6020815260006121b560208301846131ea565b60008351613453818460208801612625565b835190830190613467818360208801612625565b01949350505050565b60006020828403121561348257600080fd5b81516121b581612c7e565b601f8211156134d757600081815260208120601f850160051c810160208610156134b45750805b601f850160051c820191505b818110156134d3578281556001016134c0565b5050505b505050565b815167ffffffffffffffff8111156134f6576134f66123dd565b61350a816135048454612b7a565b8461348d565b602080601f83116001811461353f57600084156135275750858301515b600019600386901b1c1916600185901b1785556134d3565b600085815260208120601f198616915b8281101561356e5788860151825594840194600190910190840161354f565b508582101561358c5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220413e690eccee7e914a1c9e4563da1dc9c720a4e5621866c27c91713fccdf5d3764736f6c63430008110033", + "numDeployments": 5, + "solcInputHash": "49f758ec505ff69b72f3179ac11d7cfc", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_registry\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ResolverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotContract\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverNotFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverWildcardNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"metaData\",\"type\":\"bytes\"}],\"name\":\"_resolveSingle\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"batchGatewayURLs\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"}],\"name\":\"findResolver\",\"outputs\":[{\"internalType\":\"contract Resolver\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"registry\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"resolve\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"name\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveCallback\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"struct Result[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"resolveSingleCallback\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"},{\"internalType\":\"string[]\",\"name\":\"gateways\",\"type\":\"string[]\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"reverseName\",\"type\":\"bytes\"}],\"name\":\"reverse\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"reverseCallback\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_urls\",\"type\":\"string[]\"}],\"name\":\"setGatewayURLs\",\"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\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"findResolver(bytes)\":{\"details\":\"Finds a resolver by recursively querying the registry, starting at the longest name and progressively removing labels until it finds a result.\",\"params\":{\"name\":\"The name to resolve, in DNS-encoded and normalised form.\"},\"returns\":{\"_0\":\"resolver The Resolver responsible for this name.\",\"_1\":\"namehash The namehash of the full name.\",\"_2\":\"finalOffset The offset of the first label with a resolver.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions anymore. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.\"},\"resolve(bytes,bytes)\":{\"details\":\"Performs ENS name resolution for the supplied name and resolution data.\",\"params\":{\"data\":\"The resolution data, as specified in ENSIP-10.\",\"name\":\"The name to resolve, in normalised and DNS-encoded form.\"},\"returns\":{\"_0\":\"The result of resolving the name.\"}},\"reverse(bytes,string[])\":{\"details\":\"Performs ENS name reverse resolution for the supplied reverse name.\",\"params\":{\"reverseName\":\"The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\"},\"returns\":{\"_0\":\"The resolved name, the resolved address, the reverse resolver address, and the resolver address.\"}},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"The Universal Resolver is a contract that handles the work of resolving a name entirely onchain, making it possible to make a single smart contract call to resolve an ENS name.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/utils/UniversalResolver.sol\":\"UniversalResolver\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xa94b34880e3c1b0b931662cb1c09e5dfa6662f31cba80e07c5ee71cd135c9673\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC165.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n *\\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\\n */\\nabstract contract ERC165 is IERC165 {\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xd10975de010d89fd1c78dc5e8a9a7e7f496198085c151648f20cba166b32582b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface ENS {\\n // Logged when the owner of a node assigns a new owner to a subnode.\\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\\n\\n // Logged when the owner of a node transfers ownership to a new account.\\n event Transfer(bytes32 indexed node, address owner);\\n\\n // Logged when the resolver for a node changes.\\n event NewResolver(bytes32 indexed node, address resolver);\\n\\n // Logged when the TTL of a node changes\\n event NewTTL(bytes32 indexed node, uint64 ttl);\\n\\n // Logged when an operator is added or removed.\\n event ApprovalForAll(\\n address indexed owner,\\n address indexed operator,\\n bool approved\\n );\\n\\n function setRecord(\\n bytes32 node,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeRecord(\\n bytes32 node,\\n bytes32 label,\\n address owner,\\n address resolver,\\n uint64 ttl\\n ) external;\\n\\n function setSubnodeOwner(\\n bytes32 node,\\n bytes32 label,\\n address owner\\n ) external returns (bytes32);\\n\\n function setResolver(bytes32 node, address resolver) external;\\n\\n function setOwner(bytes32 node, address owner) external;\\n\\n function setTTL(bytes32 node, uint64 ttl) external;\\n\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n function owner(bytes32 node) external view returns (address);\\n\\n function resolver(bytes32 node) external view returns (address);\\n\\n function ttl(bytes32 node) external view returns (uint64);\\n\\n function recordExists(bytes32 node) external view returns (bool);\\n\\n function isApprovedForAll(\\n address owner,\\n address operator\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x7cb1158c7d268b63de1468e28e2711b28d686e2628ddb22da2149cd93ddeafda\"},\"contracts/resolvers/Resolver.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"./profiles/IABIResolver.sol\\\";\\nimport \\\"./profiles/IAddressResolver.sol\\\";\\nimport \\\"./profiles/IAddrResolver.sol\\\";\\nimport \\\"./profiles/IContentHashResolver.sol\\\";\\nimport \\\"./profiles/IDNSRecordResolver.sol\\\";\\nimport \\\"./profiles/IDNSZoneResolver.sol\\\";\\nimport \\\"./profiles/IInterfaceResolver.sol\\\";\\nimport \\\"./profiles/INameResolver.sol\\\";\\nimport \\\"./profiles/IPubkeyResolver.sol\\\";\\nimport \\\"./profiles/ITextResolver.sol\\\";\\nimport \\\"./profiles/IExtendedResolver.sol\\\";\\n\\n/**\\n * A generic resolver interface which includes all the functions including the ones deprecated\\n */\\ninterface Resolver is\\n IERC165,\\n IABIResolver,\\n IAddressResolver,\\n IAddrResolver,\\n IContentHashResolver,\\n IDNSRecordResolver,\\n IDNSZoneResolver,\\n IInterfaceResolver,\\n INameResolver,\\n IPubkeyResolver,\\n ITextResolver,\\n IExtendedResolver\\n{\\n /* Deprecated events */\\n event ContentChanged(bytes32 indexed node, bytes32 hash);\\n\\n function setApprovalForAll(address, bool) external;\\n\\n function approve(bytes32 node, address delegate, bool approved) external;\\n\\n function isApprovedForAll(address account, address operator) external;\\n\\n function isApprovedFor(\\n address owner,\\n bytes32 node,\\n address delegate\\n ) external;\\n\\n function setABI(\\n bytes32 node,\\n uint256 contentType,\\n bytes calldata data\\n ) external;\\n\\n function setAddr(bytes32 node, address addr) external;\\n\\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\\n\\n function setContenthash(bytes32 node, bytes calldata hash) external;\\n\\n function setDnsrr(bytes32 node, bytes calldata data) external;\\n\\n function setName(bytes32 node, string calldata _name) external;\\n\\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\\n\\n function setText(\\n bytes32 node,\\n string calldata key,\\n string calldata value\\n ) external;\\n\\n function setInterface(\\n bytes32 node,\\n bytes4 interfaceID,\\n address implementer\\n ) external;\\n\\n function multicall(\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n function multicallWithNodeCheck(\\n bytes32 nodehash,\\n bytes[] calldata data\\n ) external returns (bytes[] memory results);\\n\\n /* Deprecated functions */\\n function content(bytes32 node) external view returns (bytes32);\\n\\n function multihash(bytes32 node) external view returns (bytes memory);\\n\\n function setContent(bytes32 node, bytes32 hash) external;\\n\\n function setMultihash(bytes32 node, bytes calldata hash) external;\\n}\\n\",\"keccak256\":\"0xfc77ab6b7c59c3ebfe1c720bdebf9b08c2488ff7ac9501a9aa056c5d6d5b50c5\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IABIResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IABIResolver {\\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\\n\\n /**\\n * Returns the ABI associated with an ENS node.\\n * Defined in EIP205.\\n * @param node The ENS node to query\\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\\n * @return contentType The content type of the return value\\n * @return data The ABI data\\n */\\n function ABI(\\n bytes32 node,\\n uint256 contentTypes\\n ) external view returns (uint256, bytes memory);\\n}\\n\",\"keccak256\":\"0x85b373d02d19374fe570af407f459768285704bf7f30ab17c30eabfb5a10e4c3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddrResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the legacy (ETH-only) addr function.\\n */\\ninterface IAddrResolver {\\n event AddrChanged(bytes32 indexed node, address a);\\n\\n /**\\n * Returns the address associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated address.\\n */\\n function addr(bytes32 node) external view returns (address payable);\\n}\\n\",\"keccak256\":\"0x2ad7f2fc60ebe0f93745fe70247f6a854f66af732483fda2a3c5e055614445e8\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IAddressResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\n/**\\n * Interface for the new (multicoin) addr function.\\n */\\ninterface IAddressResolver {\\n event AddressChanged(\\n bytes32 indexed node,\\n uint256 coinType,\\n bytes newAddress\\n );\\n\\n function addr(\\n bytes32 node,\\n uint256 coinType\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x411447c1e90c51e09702815a85ec725ffbbe37cf96e8cc4d2a8bd4ad8a59d73e\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IContentHashResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IContentHashResolver {\\n event ContenthashChanged(bytes32 indexed node, bytes hash);\\n\\n /**\\n * Returns the contenthash associated with an ENS node.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function contenthash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xd95cd77684ba5752c428d7dceb4ecc6506ac94f4fbb910489637eb68dcd8e366\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSRecordResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSRecordResolver {\\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\\n event DNSRecordChanged(\\n bytes32 indexed node,\\n bytes name,\\n uint16 resource,\\n bytes record\\n );\\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\\n\\n /**\\n * Obtain a DNS record.\\n * @param node the namehash of the node for which to fetch the record\\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\\n * @return the DNS record in wire format if present, otherwise empty\\n */\\n function dnsRecord(\\n bytes32 node,\\n bytes32 name,\\n uint16 resource\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xcfa52200edd337f2c6c5bf402352600584da033b21323603e53de33051a3e25d\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IDNSZoneResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IDNSZoneResolver {\\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\\n event DNSZonehashChanged(\\n bytes32 indexed node,\\n bytes lastzonehash,\\n bytes zonehash\\n );\\n\\n /**\\n * zonehash obtains the hash for the zone.\\n * @param node The ENS node to query.\\n * @return The associated contenthash.\\n */\\n function zonehash(bytes32 node) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0xca1b3a16e7005533f2800a3e66fcdccf7c574deac7913d8c810f40aec1d58dc0\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IExtendedResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IExtendedResolver {\\n function resolve(\\n bytes memory name,\\n bytes memory data\\n ) external view returns (bytes memory);\\n}\\n\",\"keccak256\":\"0x5d81521cfae7d9a4475d27533cd8ed0d3475d369eb0674fd90ffbdbdf292faa3\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IInterfaceResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IInterfaceResolver {\\n event InterfaceChanged(\\n bytes32 indexed node,\\n bytes4 indexed interfaceID,\\n address implementer\\n );\\n\\n /**\\n * Returns the address of a contract that implements the specified interface for this name.\\n * If an implementer has not been set for this interfaceID and name, the resolver will query\\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\\n * will be returned.\\n * @param node The ENS node to query.\\n * @param interfaceID The EIP 165 interface ID to check for.\\n * @return The address that implements this interface, or 0 if the interface is unsupported.\\n */\\n function interfaceImplementer(\\n bytes32 node,\\n bytes4 interfaceID\\n ) external view returns (address);\\n}\\n\",\"keccak256\":\"0x390321fb58f7b927df9562450981e74b4be3907e7c09df321fd3b7409b63ae28\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/INameResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface INameResolver {\\n event NameChanged(bytes32 indexed node, string name);\\n\\n /**\\n * Returns the name associated with an ENS node, for reverse records.\\n * Defined in EIP181.\\n * @param node The ENS node to query.\\n * @return The associated name.\\n */\\n function name(bytes32 node) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x9ec392b612447b1acbdc01114f2da2837a658d3f3157f60a99c5269f0b623346\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/IPubkeyResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface IPubkeyResolver {\\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\\n\\n /**\\n * Returns the SECP256k1 public key associated with an ENS node.\\n * Defined in EIP 619.\\n * @param node The ENS node to query\\n * @return x The X coordinate of the curve point for the public key.\\n * @return y The Y coordinate of the curve point for the public key.\\n */\\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\\n}\\n\",\"keccak256\":\"0x69748947093dd2fda9ddcebd0adf19a6d1e7600df1d4b1462a0417156caddca7\",\"license\":\"MIT\"},\"contracts/resolvers/profiles/ITextResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.4;\\n\\ninterface ITextResolver {\\n event TextChanged(\\n bytes32 indexed node,\\n string indexed indexedKey,\\n string key,\\n string value\\n );\\n\\n /**\\n * Returns the text data associated with an ENS node and key.\\n * @param node The ENS node to query.\\n * @param key The text data key to query.\\n * @return The associated text data.\\n */\\n function text(\\n bytes32 node,\\n string calldata key\\n ) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x7c5debb3c42cd9f5de2274ea7aa053f238608314b62db441c40e31cea2543fd5\",\"license\":\"MIT\"},\"contracts/utils/HexUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nlibrary HexUtils {\\n /**\\n * @dev Attempts to parse bytes32 from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexStringToBytes32(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (bytes32 r, bool valid) {\\n uint256 hexLength = lastIdx - idx;\\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\\n revert(\\\"Invalid string length\\\");\\n }\\n valid = true;\\n assembly {\\n // check that the index to read to is not past the end of the string\\n if gt(lastIdx, mload(str)) {\\n revert(0, 0)\\n }\\n\\n function getHex(c) -> ascii {\\n // chars 48-57: 0-9\\n if and(gt(c, 47), lt(c, 58)) {\\n ascii := sub(c, 48)\\n leave\\n }\\n // chars 65-70: A-F\\n if and(gt(c, 64), lt(c, 71)) {\\n ascii := add(sub(c, 65), 10)\\n leave\\n }\\n // chars 97-102: a-f\\n if and(gt(c, 96), lt(c, 103)) {\\n ascii := add(sub(c, 97), 10)\\n leave\\n }\\n // invalid char\\n ascii := 0xff\\n }\\n\\n let ptr := add(str, 32)\\n for {\\n let i := idx\\n } lt(i, lastIdx) {\\n i := add(i, 2)\\n } {\\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\\n // if either byte is invalid, set invalid and break loop\\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\\n valid := false\\n break\\n }\\n let combined := or(shl(4, byte1), byte2)\\n r := or(shl(8, r), combined)\\n }\\n }\\n }\\n\\n /**\\n * @dev Attempts to parse an address from a hex string\\n * @param str The string to parse\\n * @param idx The offset to start parsing at\\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\\n */\\n function hexToAddress(\\n bytes memory str,\\n uint256 idx,\\n uint256 lastIdx\\n ) internal pure returns (address, bool) {\\n if (lastIdx - idx < 40) return (address(0x0), false);\\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\\n return (address(uint160(uint256(r))), valid);\\n }\\n}\\n\",\"keccak256\":\"0x4a8a9c72d6f3effb80b310faa6dc273e7adbc3b949df9c7a42e290e5b13519f3\",\"license\":\"MIT\"},\"contracts/utils/LowLevelCallUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\n\\nlibrary LowLevelCallUtils {\\n using Address for address;\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data\\n ) internal view returns (bool success) {\\n return functionStaticCall(target, data, gasleft());\\n }\\n\\n /**\\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\\n * `returnDataSize` and `readReturnData`.\\n * @param target The address to staticcall.\\n * @param data The data to pass to the call.\\n * @param gasLimit The gas limit to use for the call.\\n * @return success True if the call succeeded, or false if it reverts.\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n uint256 gasLimit\\n ) internal view returns (bool success) {\\n require(\\n target.isContract(),\\n \\\"LowLevelCallUtils: static call to non-contract\\\"\\n );\\n assembly {\\n success := staticcall(\\n gasLimit,\\n target,\\n add(data, 32),\\n mload(data),\\n 0,\\n 0\\n )\\n }\\n }\\n\\n /**\\n * @dev Returns the size of the return data of the most recent external call.\\n */\\n function returnDataSize() internal pure returns (uint256 len) {\\n assembly {\\n len := returndatasize()\\n }\\n }\\n\\n /**\\n * @dev Reads return data from the most recent external call.\\n * @param offset Offset into the return data.\\n * @param length Number of bytes to return.\\n */\\n function readReturnData(\\n uint256 offset,\\n uint256 length\\n ) internal pure returns (bytes memory data) {\\n data = new bytes(length);\\n assembly {\\n returndatacopy(add(data, 32), offset, length)\\n }\\n }\\n\\n /**\\n * @dev Reverts with the return data from the most recent external call.\\n */\\n function propagateRevert() internal pure {\\n assembly {\\n returndatacopy(0, 0, returndatasize())\\n revert(0, returndatasize())\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba30d0a44a6a2f1557e4913108b25d8b36cb40a54f44ac98086465d6bf77c5e6\",\"license\":\"MIT\"},\"contracts/utils/NameEncoder.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.13;\\n\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\n\\nlibrary NameEncoder {\\n using BytesUtils for bytes;\\n\\n function dnsEncodeName(\\n string memory name\\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\\n uint8 labelLength = 0;\\n bytes memory bytesName = bytes(name);\\n uint256 length = bytesName.length;\\n dnsName = new bytes(length + 2);\\n node = 0;\\n if (length == 0) {\\n dnsName[0] = 0;\\n return (dnsName, node);\\n }\\n\\n // use unchecked to save gas since we check for an underflow\\n // and we check for the length before the loop\\n unchecked {\\n for (uint256 i = length - 1; i >= 0; i--) {\\n if (bytesName[i] == \\\".\\\") {\\n dnsName[i + 1] = bytes1(labelLength);\\n node = keccak256(\\n abi.encodePacked(\\n node,\\n bytesName.keccak(i + 1, labelLength)\\n )\\n );\\n labelLength = 0;\\n } else {\\n labelLength += 1;\\n dnsName[i + 1] = bytesName[i];\\n }\\n if (i == 0) {\\n break;\\n }\\n }\\n }\\n\\n node = keccak256(\\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\\n );\\n\\n dnsName[0] = bytes1(labelLength);\\n return (dnsName, node);\\n }\\n}\\n\",\"keccak256\":\"0x63fd5f360cef8c9b8b8cfdff20d3f0e955b4c8ac7dfac758788223c61678aad1\",\"license\":\"MIT\"},\"contracts/utils/UniversalResolver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >=0.8.17 <0.9.0;\\n\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {LowLevelCallUtils} from \\\"./LowLevelCallUtils.sol\\\";\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {IExtendedResolver} from \\\"../resolvers/profiles/IExtendedResolver.sol\\\";\\nimport {Resolver, INameResolver, IAddrResolver} from \\\"../resolvers/Resolver.sol\\\";\\nimport {NameEncoder} from \\\"./NameEncoder.sol\\\";\\nimport {BytesUtils} from \\\"../wrapper/BytesUtils.sol\\\";\\nimport {HexUtils} from \\\"./HexUtils.sol\\\";\\n\\nerror OffchainLookup(\\n address sender,\\n string[] urls,\\n bytes callData,\\n bytes4 callbackFunction,\\n bytes extraData\\n);\\n\\nerror ResolverNotFound();\\n\\nerror ResolverWildcardNotSupported();\\n\\nerror ResolverNotContract();\\n\\nerror ResolverError(bytes returnData);\\n\\nerror HttpError(HttpErrorItem[] errors);\\n\\nstruct HttpErrorItem {\\n uint16 status;\\n string message;\\n}\\n\\nstruct MulticallData {\\n bytes name;\\n bytes[] data;\\n string[] gateways;\\n bytes4 callbackFunction;\\n bool isWildcard;\\n address resolver;\\n bytes metaData;\\n bool[] failures;\\n}\\n\\nstruct MulticallChecks {\\n bool isCallback;\\n bool hasExtendedResolver;\\n}\\n\\nstruct OffchainLookupCallData {\\n address sender;\\n string[] urls;\\n bytes callData;\\n}\\n\\nstruct OffchainLookupExtraData {\\n bytes4 callbackFunction;\\n bytes data;\\n}\\n\\nstruct Result {\\n bool success;\\n bytes returnData;\\n}\\n\\ninterface BatchGateway {\\n function query(\\n OffchainLookupCallData[] memory data\\n ) external returns (bool[] memory failures, bytes[] memory responses);\\n}\\n\\n/**\\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\\n * making it possible to make a single smart contract call to resolve an ENS name.\\n */\\ncontract UniversalResolver is ERC165, Ownable {\\n using Address for address;\\n using NameEncoder for string;\\n using BytesUtils for bytes;\\n using HexUtils for bytes;\\n\\n string[] public batchGatewayURLs;\\n ENS public immutable registry;\\n\\n constructor(address _registry, string[] memory _urls) {\\n registry = ENS(_registry);\\n batchGatewayURLs = _urls;\\n }\\n\\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\\n batchGatewayURLs = _urls;\\n }\\n\\n /**\\n * @dev Performs ENS name resolution for the supplied name and resolution data.\\n * @param name The name to resolve, in normalised and DNS-encoded form.\\n * @param data The resolution data, as specified in ENSIP-10.\\n * @return The result of resolving the name.\\n */\\n function resolve(\\n bytes calldata name,\\n bytes memory data\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n batchGatewayURLs,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data\\n ) external view returns (Result[] memory, address) {\\n return resolve(name, data, batchGatewayURLs);\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways\\n ) external view returns (bytes memory, address) {\\n return\\n _resolveSingle(\\n name,\\n data,\\n gateways,\\n this.resolveSingleCallback.selector,\\n \\\"\\\"\\n );\\n }\\n\\n function resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways\\n ) public view returns (Result[] memory, address) {\\n return\\n _resolve(name, data, gateways, this.resolveCallback.selector, \\\"\\\");\\n }\\n\\n function _resolveSingle(\\n bytes calldata name,\\n bytes memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) public view returns (bytes memory, address) {\\n bytes[] memory dataArr = new bytes[](1);\\n dataArr[0] = data;\\n (Result[] memory results, address resolver) = _resolve(\\n name,\\n dataArr,\\n gateways,\\n callbackFunction,\\n metaData\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function _resolve(\\n bytes calldata name,\\n bytes[] memory data,\\n string[] memory gateways,\\n bytes4 callbackFunction,\\n bytes memory metaData\\n ) internal view returns (Result[] memory results, address resolverAddress) {\\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\\n resolverAddress = address(resolver);\\n if (resolverAddress == address(0)) {\\n revert ResolverNotFound();\\n }\\n\\n if (!resolverAddress.isContract()) {\\n revert ResolverNotContract();\\n }\\n\\n bool isWildcard = finalOffset != 0;\\n\\n results = _multicall(\\n MulticallData(\\n name,\\n data,\\n gateways,\\n callbackFunction,\\n isWildcard,\\n resolverAddress,\\n metaData,\\n new bool[](data.length)\\n )\\n );\\n }\\n\\n function reverse(\\n bytes calldata reverseName\\n ) external view returns (string memory, address, address, address) {\\n return reverse(reverseName, batchGatewayURLs);\\n }\\n\\n /**\\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\\n */\\n function reverse(\\n bytes calldata reverseName,\\n string[] memory gateways\\n ) public view returns (string memory, address, address, address) {\\n bytes memory encodedCall = abi.encodeCall(\\n INameResolver.name,\\n reverseName.namehash(0)\\n );\\n (\\n bytes memory reverseResolvedData,\\n address reverseResolverAddress\\n ) = _resolveSingle(\\n reverseName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n \\\"\\\"\\n );\\n\\n return\\n getForwardDataFromReverse(\\n reverseResolvedData,\\n reverseResolverAddress,\\n gateways\\n );\\n }\\n\\n function getForwardDataFromReverse(\\n bytes memory resolvedReverseData,\\n address reverseResolverAddress,\\n string[] memory gateways\\n ) internal view returns (string memory, address, address, address) {\\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\\n\\n (bytes memory encodedName, bytes32 namehash) = resolvedName\\n .dnsEncodeName();\\n\\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\\n bytes memory metaData = abi.encode(\\n resolvedName,\\n reverseResolverAddress\\n );\\n (bytes memory resolvedData, address resolverAddress) = this\\n ._resolveSingle(\\n encodedName,\\n encodedCall,\\n gateways,\\n this.reverseCallback.selector,\\n metaData\\n );\\n\\n address resolvedAddress = abi.decode(resolvedData, (address));\\n\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n function resolveSingleCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (bytes memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveSingleCallback.selector\\n );\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n return (result.returnData, resolver);\\n }\\n\\n function resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (Result[] memory, address) {\\n (Result[] memory results, address resolver, , ) = _resolveCallback(\\n response,\\n extraData,\\n this.resolveCallback.selector\\n );\\n return (results, resolver);\\n }\\n\\n function reverseCallback(\\n bytes calldata response,\\n bytes calldata extraData\\n ) external view returns (string memory, address, address, address) {\\n (\\n Result[] memory results,\\n address resolverAddress,\\n string[] memory gateways,\\n bytes memory metaData\\n ) = _resolveCallback(\\n response,\\n extraData,\\n this.reverseCallback.selector\\n );\\n\\n Result memory result = results[0];\\n\\n _checkResolveSingle(result);\\n\\n if (metaData.length > 0) {\\n (string memory resolvedName, address reverseResolverAddress) = abi\\n .decode(metaData, (string, address));\\n address resolvedAddress = abi.decode(result.returnData, (address));\\n return (\\n resolvedName,\\n resolvedAddress,\\n reverseResolverAddress,\\n resolverAddress\\n );\\n }\\n\\n return\\n getForwardDataFromReverse(\\n result.returnData,\\n resolverAddress,\\n gateways\\n );\\n }\\n\\n function supportsInterface(\\n bytes4 interfaceId\\n ) public view virtual override returns (bool) {\\n return\\n interfaceId == type(IExtendedResolver).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n function _resolveCallback(\\n bytes calldata response,\\n bytes calldata extraData,\\n bytes4 callbackFunction\\n )\\n internal\\n view\\n returns (Result[] memory, address, string[] memory, bytes memory)\\n {\\n MulticallData memory multicallData;\\n multicallData.callbackFunction = callbackFunction;\\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\\n response,\\n (bool[], bytes[])\\n );\\n OffchainLookupExtraData[] memory extraDatas;\\n (\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n ) = abi.decode(\\n extraData,\\n (bool, address, string[], bytes, OffchainLookupExtraData[])\\n );\\n require(responses.length <= extraDatas.length);\\n multicallData.data = new bytes[](extraDatas.length);\\n multicallData.failures = new bool[](extraDatas.length);\\n uint256 offchainCount = 0;\\n for (uint256 i = 0; i < extraDatas.length; i++) {\\n if (extraDatas[i].callbackFunction == bytes4(0)) {\\n // This call did not require an offchain lookup; use the previous input data.\\n multicallData.data[i] = extraDatas[i].data;\\n } else {\\n if (failures[offchainCount]) {\\n multicallData.failures[i] = true;\\n multicallData.data[i] = responses[offchainCount];\\n } else {\\n multicallData.data[i] = abi.encodeWithSelector(\\n extraDatas[i].callbackFunction,\\n responses[offchainCount],\\n extraDatas[i].data\\n );\\n }\\n offchainCount = offchainCount + 1;\\n }\\n }\\n\\n return (\\n _multicall(multicallData),\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData\\n );\\n }\\n\\n /**\\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\\n * the error with the data necessary to continue the request where it left off.\\n * @param target The address to call.\\n * @param data The data to call `target` with.\\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\\n * @return result Whether the call succeeded.\\n */\\n function callWithOffchainLookupPropagation(\\n address target,\\n bytes memory data,\\n bool isSafe\\n )\\n internal\\n view\\n returns (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool result\\n )\\n {\\n if (isSafe) {\\n result = LowLevelCallUtils.functionStaticCall(target, data);\\n } else {\\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\\n }\\n uint256 size = LowLevelCallUtils.returnDataSize();\\n\\n if (result) {\\n return (\\n false,\\n LowLevelCallUtils.readReturnData(0, size),\\n extraData,\\n true\\n );\\n }\\n\\n // Failure\\n if (size >= 4) {\\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\\n // Offchain lookup. Decode the revert message and create our own that nests it.\\n bytes memory revertData = LowLevelCallUtils.readReturnData(\\n 4,\\n size - 4\\n );\\n if (bytes4(errorId) == OffchainLookup.selector) {\\n (\\n address wrappedSender,\\n string[] memory wrappedUrls,\\n bytes memory wrappedCallData,\\n bytes4 wrappedCallbackFunction,\\n bytes memory wrappedExtraData\\n ) = abi.decode(\\n revertData,\\n (address, string[], bytes, bytes4, bytes)\\n );\\n if (wrappedSender == target) {\\n returnData = abi.encode(\\n OffchainLookupCallData(\\n wrappedSender,\\n wrappedUrls,\\n wrappedCallData\\n )\\n );\\n extraData = OffchainLookupExtraData(\\n wrappedCallbackFunction,\\n wrappedExtraData\\n );\\n return (true, returnData, extraData, false);\\n }\\n } else {\\n returnData = bytes.concat(errorId, revertData);\\n return (false, returnData, extraData, false);\\n }\\n }\\n }\\n\\n /**\\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\\n * removing labels until it finds a result.\\n * @param name The name to resolve, in DNS-encoded and normalised form.\\n * @return resolver The Resolver responsible for this name.\\n * @return namehash The namehash of the full name.\\n * @return finalOffset The offset of the first label with a resolver.\\n */\\n function findResolver(\\n bytes calldata name\\n ) public view returns (Resolver, bytes32, uint256) {\\n (\\n address resolver,\\n bytes32 namehash,\\n uint256 finalOffset\\n ) = findResolver(name, 0);\\n return (Resolver(resolver), namehash, finalOffset);\\n }\\n\\n function findResolver(\\n bytes calldata name,\\n uint256 offset\\n ) internal view returns (address, bytes32, uint256) {\\n uint256 labelLength = uint256(uint8(name[offset]));\\n if (labelLength == 0) {\\n return (address(0), bytes32(0), offset);\\n }\\n uint256 nextLabel = offset + labelLength + 1;\\n bytes32 labelHash;\\n if (\\n labelLength == 66 &&\\n // 0x5b == '['\\n name[offset + 1] == 0x5b &&\\n // 0x5d == ']'\\n name[nextLabel - 1] == 0x5d\\n ) {\\n // Encrypted label\\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\\n .hexStringToBytes32(0, 64);\\n } else {\\n labelHash = keccak256(name[offset + 1:nextLabel]);\\n }\\n (\\n address parentresolver,\\n bytes32 parentnode,\\n uint256 parentoffset\\n ) = findResolver(name, nextLabel);\\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\\n address resolver = registry.resolver(node);\\n if (resolver != address(0)) {\\n return (resolver, node, offset);\\n }\\n return (parentresolver, node, parentoffset);\\n }\\n\\n function _checkInterface(\\n address resolver,\\n bytes4 interfaceId\\n ) internal view returns (bool) {\\n try\\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\\n returns (bool supported) {\\n return supported;\\n } catch {\\n return false;\\n }\\n }\\n\\n function _checkSafetyAndItem(\\n bytes memory name,\\n bytes memory item,\\n address resolver,\\n MulticallChecks memory multicallChecks\\n ) internal view returns (bool, bytes memory) {\\n if (!multicallChecks.isCallback) {\\n if (multicallChecks.hasExtendedResolver) {\\n return (\\n true,\\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\\n );\\n }\\n return (_checkInterface(resolver, bytes4(item)), item);\\n }\\n return (true, item);\\n }\\n\\n function _checkMulticall(\\n MulticallData memory multicallData\\n ) internal view returns (MulticallChecks memory) {\\n bool isCallback = multicallData.name.length == 0;\\n bool hasExtendedResolver = _checkInterface(\\n multicallData.resolver,\\n type(IExtendedResolver).interfaceId\\n );\\n\\n if (multicallData.isWildcard && !hasExtendedResolver) {\\n revert ResolverWildcardNotSupported();\\n }\\n\\n return MulticallChecks(isCallback, hasExtendedResolver);\\n }\\n\\n function _checkResolveSingle(Result memory result) internal pure {\\n if (!result.success) {\\n if (bytes4(result.returnData) == HttpError.selector) {\\n bytes memory returnData = result.returnData;\\n assembly {\\n revert(add(returnData, 32), mload(returnData))\\n }\\n }\\n revert ResolverError(result.returnData);\\n }\\n }\\n\\n function _multicall(\\n MulticallData memory multicallData\\n ) internal view returns (Result[] memory results) {\\n uint256 length = multicallData.data.length;\\n uint256 offchainCount = 0;\\n OffchainLookupCallData[]\\n memory callDatas = new OffchainLookupCallData[](length);\\n OffchainLookupExtraData[]\\n memory extraDatas = new OffchainLookupExtraData[](length);\\n results = new Result[](length);\\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\\n\\n for (uint256 i = 0; i < length; i++) {\\n bytes memory item = multicallData.data[i];\\n bool failure = multicallData.failures[i];\\n\\n if (failure) {\\n results[i] = Result(false, item);\\n continue;\\n }\\n\\n bool isSafe = false;\\n (isSafe, item) = _checkSafetyAndItem(\\n multicallData.name,\\n item,\\n multicallData.resolver,\\n multicallChecks\\n );\\n\\n (\\n bool offchain,\\n bytes memory returnData,\\n OffchainLookupExtraData memory extraData,\\n bool success\\n ) = callWithOffchainLookupPropagation(\\n multicallData.resolver,\\n item,\\n isSafe\\n );\\n\\n if (offchain) {\\n callDatas[offchainCount] = abi.decode(\\n returnData,\\n (OffchainLookupCallData)\\n );\\n extraDatas[i] = extraData;\\n offchainCount += 1;\\n continue;\\n }\\n\\n if (success && multicallChecks.hasExtendedResolver) {\\n // if this is a successful resolve() call, unwrap the result\\n returnData = abi.decode(returnData, (bytes));\\n }\\n results[i] = Result(success, returnData);\\n extraDatas[i].data = item;\\n }\\n\\n if (offchainCount == 0) {\\n return results;\\n }\\n\\n // Trim callDatas if offchain data exists\\n assembly {\\n mstore(callDatas, offchainCount)\\n }\\n\\n revert OffchainLookup(\\n address(this),\\n multicallData.gateways,\\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\\n multicallData.callbackFunction,\\n abi.encode(\\n multicallData.isWildcard,\\n multicallData.resolver,\\n multicallData.gateways,\\n multicallData.metaData,\\n extraDatas\\n )\\n );\\n }\\n}\\n\",\"keccak256\":\"0x2a03a3a94a411b599690e58634c2c5695561cbe4a16fae60cbfefa872a6c2f7b\",\"license\":\"MIT\"},\"contracts/wrapper/BytesUtils.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma solidity ~0.8.17;\\n\\nlibrary BytesUtils {\\n /*\\n * @dev Returns the keccak-256 hash of a byte range.\\n * @param self The byte string to hash.\\n * @param offset The position to start hashing at.\\n * @param len The number of bytes to hash.\\n * @return The hash of the byte range.\\n */\\n function keccak(\\n bytes memory self,\\n uint256 offset,\\n uint256 len\\n ) internal pure returns (bytes32 ret) {\\n require(offset + len <= self.length);\\n assembly {\\n ret := keccak256(add(add(self, 32), offset), len)\\n }\\n }\\n\\n /**\\n * @dev Returns the ENS namehash of a DNS-encoded name.\\n * @param self The DNS-encoded name to hash.\\n * @param offset The offset at which to start hashing.\\n * @return The namehash of the name.\\n */\\n function namehash(\\n bytes memory self,\\n uint256 offset\\n ) internal pure returns (bytes32) {\\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\\n if (labelhash == bytes32(0)) {\\n require(offset == self.length - 1, \\\"namehash: Junk at end of name\\\");\\n return bytes32(0);\\n }\\n return\\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\\n }\\n\\n /**\\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\\n * @param self The byte string to read a label from.\\n * @param idx The index to read a label at.\\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\\n * @return newIdx The index of the start of the next label.\\n */\\n function readLabel(\\n bytes memory self,\\n uint256 idx\\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\\n require(idx < self.length, \\\"readLabel: Index out of bounds\\\");\\n uint256 len = uint256(uint8(self[idx]));\\n if (len > 0) {\\n labelhash = keccak(self, idx + 1, len);\\n } else {\\n labelhash = bytes32(0);\\n }\\n newIdx = idx + len + 1;\\n }\\n}\\n\",\"keccak256\":\"0xf862cd86d749158a554e3cb517efa9097331ec0cf7225117f21e96fb50c67edb\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162003b0f38038062003b0f8339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613650620004bf600039600081816101ea01526114fc01526136506000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e6101493660046123d3565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125f3565b61035c565b60405161015a9291906126d1565b61019761019236600461277c565b610392565b60405161015a9291906127e5565b6101b86101b336600461286e565b61047f565b60405161015a94939291906128da565b6101d0610547565b005b6101976101e0366004612916565b61055b565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b610176610243366004612975565b610583565b6101d0610256366004612a3b565b610626565b610176610269366004612a78565b610645565b61028161027c366004612ad7565b61073e565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612b19565b610764565b60405161015a9190612b32565b6101b86102d4366004612b45565b610810565b6101976102e736600461286e565b610902565b6101766102fa36600461286e565b610946565b6101b861030d366004612ad7565b6109b8565b6101d0610320366004612bb9565b610aab565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b60405180602001604052806000815250610583565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612bd6565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612bd6565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b5050505061055b565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b40565b93509350935093506000846000815181106104ba576104ba612c10565b602002602001015190506104cd81610ec6565b81511561051f57600080838060200190518101906104eb9190612c6b565b91509150600083602001518060200190518101906105099190612cbd565b929b50919950975093955061053c945050505050565b61052e81602001518585610f51565b985098509850985050505050505b945094509450949050565b61054f6110b2565b610559600061110c565b565b606060006103848686868663b4a8580160e01b60405180602001604052806000815250611174565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059f57905050905086816000815181106105ca576105ca612c10565b60200260200101819052506000806105e68b8b858b8b8b611174565b915091506000826000815181106105ff576105ff612c10565b6020026020010151905061061281610ec6565b602001519b909a5098505050505050505050565b61062e6110b2565b8051610641906001906020840190612300565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561071d57838290600052602060002001805461069090612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546106bc90612bd6565b80156107095780601f106106de57610100808354040283529160200191610709565b820191906000526020600020905b8154815290600101906020018083116106ec57829003601f168201915b505050505081526020019060010190610671565b5050505063e0a8541260e01b60405180602001604052806000815250610583565b600080600080600080610753888860006112f5565b919750955093505050509250925092565b6001818154811061077457600080fd5b90600052602060002001600091509050805461078f90612bd6565b80601f01602080910402602001604051908101604052809291908181526020018280546107bb90612bd6565b80156108085780601f106107dd57610100808354040283529160200191610808565b820191906000526020600020905b8154815290600101906020018083116107eb57829003601f168201915b505050505081565b606060008060008061085c600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115a39050565b60405160240161086e91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108de908b908b9086908c90636dc4fb7360e01b90610583565b915091506108ed82828a610f51565b96509650965096505050505b93509350935093565b606060008080610935888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b40565b50919a909950975050505050505050565b606060008080610979888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b40565b50509150915060008260008151811061099457610994612c10565b602002602001015190506109a781610ec6565b602001519890975095505050505050565b60606000806000610a9b86866001805480602002602001604051908101604052809291908181526020016000905b82821015610a92578382906000526020600020018054610a0590612bd6565b80601f0160208091040260200160405190810160405280929190818152602001828054610a3190612bd6565b8015610a7e5780601f10610a5357610100808354040283529160200191610a7e565b820191906000526020600020905b815481529060010190602001808311610a6157829003601f168201915b5050505050815260200190600101906109e6565b50505050610810565b9299919850965090945092505050565b610ab36110b2565b6001600160a01b038116610b345760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b3d8161110c565b50565b60606000606080610ba460405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610bc38b8d018d612ce8565b90925090506060610bd68a8c018c612da0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c1057600080fd5b805167ffffffffffffffff811115610c2a57610c2a612439565b604051908082528060200260200182016040528015610c5d57816020015b6060815260200190600190039081610c485790505b506020850152805167ffffffffffffffff811115610c7d57610c7d612439565b604051908082528060200260200182016040528015610ca6578160200160208202803683370190505b5060e08501526000805b8251811015610e94578251600090849083908110610cd057610cd0612c10565b6020026020010151600001516001600160e01b03191603610d2f57828181518110610cfd57610cfd612c10565b60200260200101516020015186602001518281518110610d1f57610d1f612c10565b6020026020010181905250610e82565b848281518110610d4157610d41612c10565b602002602001015115610db85760018660e001518281518110610d6657610d66612c10565b602002602001019015159081151581525050838281518110610d8a57610d8a612c10565b602002602001015186602001518281518110610da857610da8612c10565b6020026020010181905250610e74565b828181518110610dca57610dca612c10565b602002602001015160000151848381518110610de857610de8612c10565b6020026020010151848381518110610e0257610e02612c10565b602002602001015160200151604051602401610e1f929190612f24565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e6857610e68612c10565b60200260200101819052505b610e7f826001612f68565b91505b80610e8c81612f7b565b915050610cb0565b50610e9e85611662565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b8051610b3d5760208101517fca7a4e750000000000000000000000000000000000000000000000000000000090610efc90612f94565b6001600160e01b03191603610f1957602080820151805190918201fd5b80602001516040517f95c0c752000000000000000000000000000000000000000000000000000000008152600401610b2b9190612b32565b606060008060008087806020019051810190610f6d9190612fcc565b9050600080610f7b83611a50565b91509150600081604051602401610f9491815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610fee9187918e91016126d1565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b815260040161103d959493929190613056565b600060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110829190810190612c6b565b9150915060008280602001905181019061109c9190612cbd565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105595760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b2b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006111858a8a61073e565b919450849350909150506001600160a01b0382166111cf576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b611210576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b8152831515926112e5929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff8111156112b4576112b4612439565b6040519080825280602002602001820160405280156112dd578160200160208202803683370190505b509052611662565b9450505050965096945050505050565b60008060008086868681811061130d5761130d612c10565b919091013560f81c915050600081900361133157506000925082915083905061159a565b600061133d8287612f68565b611348906001612f68565b9050600082604214801561138e57508888611364896001612f68565b81811061137357611373612c10565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113cc575088886113a26001856130bf565b8181106113b1576113b1612c10565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156114445761143c600060408b8b6113e58c6002612f68565b906113f16001896130bf565b926113fe939291906130d2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611c799050565b509050611476565b8888611451896001612f68565b61145d928592906130d2565b60405161146b9291906130fc565b604051809103902090505b60008060006114868c8c876112f5565b925092509250600082856040516020016114aa929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115679190612cbd565b90506001600160a01b0381161561158b579950975089965061159a95505050505050565b50929850919650909450505050505b93509350939050565b60008060006115b28585611dcd565b90925090508161162457600185516115ca91906130bf565b84146116185760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b2b565b50600091506103569050565b61162e85826115a3565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561168757611687612439565b6040519080825280602002602001820160405280156116e557816020015b6116d2604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116a55790505b50905060008367ffffffffffffffff81111561170357611703612439565b60405190808252806020026020018201604052801561174957816020015b6040805180820190915260008152606060208201528152602001906001900390816117215790505b5090508367ffffffffffffffff81111561176557611765612439565b6040519080825280602002602001820160405280156117ab57816020015b6040805180820190915260008152606060208201528152602001906001900390816117835790505b50945060006117b987611e84565b905060005b8581101561198f576000886020015182815181106117de576117de612c10565b6020026020010151905060008960e00151838151811061180057611800612c10565b60200260200101519050801561184c5760405180604001604052806000151581526020018381525089848151811061183a5761183a612c10565b6020026020010181905250505061197d565b60006118628b60000151848d60a0015188611f1b565b809450819250505060008060008061187f8f60a001518887611fa3565b935093509350935083156118f557828060200190518101906118a1919061318c565b8b8d815181106118b3576118b3612c10565b6020026020010181905250818a89815181106118d1576118d1612c10565b60209081029190910101526118e760018d612f68565b9b505050505050505061197d565b808015611903575088602001515b1561191f578280602001905181019061191c9190612fcc565b92505b60405180604001604052808215158152602001848152508e898151811061194857611948612c10565b6020026020010181905250868a898151811061196657611966612c10565b602002602001015160200181905250505050505050505b8061198781612f7b565b9150506117be565b50836000036119a2575050505050919050565b83835230876040015163a780bab660e01b856040516024016119c49190613287565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a259594939291906132e9565b60408051601f1981840301815290829052630556f18360e41b8252610b2b95949392916004016133a6565b805160609060009081908490611a67816002612f68565b67ffffffffffffffff811115611a7f57611a7f612439565b6040519080825280601f01601f191660200182016040528015611aa9576020820181803683370190505b50945060009350808403611aee57600060f81b85600081518110611acf57611acf612c10565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b0657611b06612c10565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611bc8578360f81b868260010181518110611b6c57611b6c612c10565b60200101906001600160f81b031916908160001a90535084611b95846001840160ff881661215b565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c18565b600184019350828181518110611be057611be0612c10565b602001015160f81c60f81b868260010181518110611c0057611c00612c10565b60200101906001600160f81b031916908160001a9053505b8015611c275760001901611af4565b5083611c3883600060ff871661215b565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611acf57611acf612c10565b60008080611c8785856130bf565b905080604014158015611c9b575080602814155b80611cb05750611cac6002826133da565b6001145b15611cfd5760405162461bcd60e51b815260206004820152601560248201527f496e76616c696420737472696e67206c656e67746800000000000000000000006044820152606401610b2b565b600191508551841115611d0f57600080fd5b611d60565b6000603a8210602f83111615611d2c5750602f190190565b60478210604083111615611d4257506036190190565b60678210606083111615611d5857506056190190565b5060ff919050565b60208601855b85811015611dc257611d7d8183015160001a611d14565b611d8f6001830184015160001a611d14565b60ff811460ff83141715611da857600095505050611dc2565b60049190911b1760089590951b9490941793600201611d66565b505050935093915050565b60008083518310611e205760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b2b565b6000848481518110611e3457611e34612c10565b016020015160f81c90508015611e6057611e5985611e53866001612f68565b8361215b565b9250611e65565b600092505b611e6f8185612f68565b611e7a906001612f68565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611eb790639061b92360e01b61217f565b905083608001518015611ec8575080155b15611eff576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f9757826020015115611f7b5760018686604051602401611f47929190612f24565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f8d84611f8887612f94565b61217f565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611fd657611fcf8787612204565b9050611fe6565b611fe3878761c350612218565b90505b3d811561200a576000611ffa6000836122ab565b9095509350600191506108f99050565b60048110612151576000612020600060046122ab565b90506000612038600461203381866130bf565b6122ab565b9050630556f18360e41b61204b83612f94565b6001600160e01b031916036121195760008060008060008580602001905181019061207691906133fc565b945094509450945094508e6001600160a01b0316856001600160a01b03160361210f576040518060600160405280866001600160a01b03168152602001858152602001848152506040516020016120cd91906134ac565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108f995505050505050565b505050505061214e565b818160405160200161212c9291906134bf565b60408051601f198184030181529190526000975095508693506108f992505050565b50505b5093509350935093565b825160009061216a8385612f68565b111561217557600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121f1575060408051601f3d908101601f191682019092526121ee918101906134ee565b60015b6121fd57506000610356565b9050610356565b600061221183835a612218565b9392505050565b60006001600160a01b0384163b6122975760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b2b565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff8111156122c6576122c6612439565b6040519080825280601f01601f1916602001820160405280156122f0576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612346579160200282015b828111156123465782518290612336908261355a565b5091602001919060010190612320565b50612352929150612356565b5090565b8082111561235257600061236a8282612373565b50600101612356565b50805461237f90612bd6565b6000825580601f1061238f575050565b601f016020900490600052602060002090810190610b3d91905b8082111561235257600081556001016123a9565b6001600160e01b031981168114610b3d57600080fd5b6000602082840312156123e557600080fd5b8135612211816123bd565b60008083601f84011261240257600080fd5b50813567ffffffffffffffff81111561241a57600080fd5b60208301915083602082850101111561243257600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561247257612472612439565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156124a1576124a1612439565b604052919050565b600067ffffffffffffffff8211156124c3576124c3612439565b50601f01601f191660200190565b60006124e46124df846124a9565b612478565b90508281528383830111156124f857600080fd5b828260208301376000602084830101529392505050565b600082601f83011261252057600080fd5b612211838335602085016124d1565b600067ffffffffffffffff82111561254957612549612439565b5060051b60200190565b600082601f83011261256457600080fd5b813560206125746124df8361252f565b82815260059290921b8401810191818101908684111561259357600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156125b75760008081fd5b8701603f810189136125c95760008081fd5b6125da8986830135604084016124d1565b845250918301918301612597565b509695505050505050565b6000806000806060858703121561260957600080fd5b843567ffffffffffffffff8082111561262157600080fd5b61262d888389016123f0565b9096509450602087013591508082111561264657600080fd5b6126528883890161250f565b9350604087013591508082111561266857600080fd5b5061267587828801612553565b91505092959194509250565b60005b8381101561269c578181015183820152602001612684565b50506000910152565b600081518084526126bd816020860160208601612681565b601f01601f19169290920160200192915050565b6040815260006126e460408301856126a5565b90506001600160a01b03831660208301529392505050565b600082601f83011261270d57600080fd5b8135602061271d6124df8361252f565b82815260059290921b8401810191818101908684111561273c57600080fd5b8286015b848110156125e857803567ffffffffffffffff8111156127605760008081fd5b61276e8986838b010161250f565b845250918301918301612740565b60008060006040848603121561279157600080fd5b833567ffffffffffffffff808211156127a957600080fd5b6127b5878388016123f0565b909550935060208601359150808211156127ce57600080fd5b506127db868287016126fc565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561284f57888603605f19018552815180511515875283015183870188905261283c888801826126a5565b965050938201939082019060010161280e565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561288457600080fd5b843567ffffffffffffffff8082111561289c57600080fd5b6128a8888389016123f0565b909650945060208701359150808211156128c157600080fd5b506128ce878288016123f0565b95989497509550505050565b6080815260006128ed60808301876126a5565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561292c57600080fd5b843567ffffffffffffffff8082111561294457600080fd5b612950888389016123f0565b9096509450602087013591508082111561296957600080fd5b612652888389016126fc565b60008060008060008060a0878903121561298e57600080fd5b863567ffffffffffffffff808211156129a657600080fd5b6129b28a838b016123f0565b909850965060208901359150808211156129cb57600080fd5b6129d78a838b0161250f565b955060408901359150808211156129ed57600080fd5b6129f98a838b01612553565b945060608901359150612a0b826123bd565b90925060808801359080821115612a2157600080fd5b50612a2e89828a0161250f565b9150509295509295509295565b600060208284031215612a4d57600080fd5b813567ffffffffffffffff811115612a6457600080fd5b612a7084828501612553565b949350505050565b600080600060408486031215612a8d57600080fd5b833567ffffffffffffffff80821115612aa557600080fd5b612ab1878388016123f0565b90955093506020860135915080821115612aca57600080fd5b506127db8682870161250f565b60008060208385031215612aea57600080fd5b823567ffffffffffffffff811115612b0157600080fd5b612b0d858286016123f0565b90969095509350505050565b600060208284031215612b2b57600080fd5b5035919050565b60208152600061221160208301846126a5565b600080600060408486031215612b5a57600080fd5b833567ffffffffffffffff80821115612b7257600080fd5b612b7e878388016123f0565b90955093506020860135915080821115612b9757600080fd5b506127db86828701612553565b6001600160a01b0381168114610b3d57600080fd5b600060208284031215612bcb57600080fd5b813561221181612ba4565b600181811c90821680612bea57607f821691505b602082108103612c0a57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612c3757600080fd5b8151612c456124df826124a9565b818152846020838601011115612c5a57600080fd5b612a70826020830160208701612681565b60008060408385031215612c7e57600080fd5b825167ffffffffffffffff811115612c9557600080fd5b612ca185828601612c26565b9250506020830151612cb281612ba4565b809150509250929050565b600060208284031215612ccf57600080fd5b815161221181612ba4565b8015158114610b3d57600080fd5b60008060408385031215612cfb57600080fd5b823567ffffffffffffffff80821115612d1357600080fd5b818501915085601f830112612d2757600080fd5b81356020612d376124df8361252f565b82815260059290921b84018101918181019089841115612d5657600080fd5b948201945b83861015612d7d578535612d6e81612cda565b82529482019490820190612d5b565b96505086013592505080821115612d9357600080fd5b50611e7a858286016126fc565b600080600080600060a08688031215612db857600080fd5b612dc28635612cda565b85359450612dd36020870135612ba4565b6020860135935067ffffffffffffffff8060408801351115612df457600080fd5b612e048860408901358901612553565b93508060608801351115612e1757600080fd5b612e27886060890135890161250f565b92508060808801351115612e3a57600080fd5b6080870135870188601f820112612e5057600080fd5b612e5d6124df823561252f565b81358082526020808301929160051b8401018b1015612e7b57600080fd5b602083015b6020843560051b850101811015612f12578481351115612e9f57600080fd5b803584016040818e03601f19011215612eb757600080fd5b612ebf61244f565b612ecc60208301356123bd565b602082013581528660408301351115612ee457600080fd5b612ef78e6020604085013585010161250f565b60208201528085525050602083019250602081019050612e80565b50809450505050509295509295909350565b604081526000612f3760408301856126a5565b8281036020840152612f4981856126a5565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f52565b600060018201612f8d57612f8d612f52565b5060010190565b6000815160208301516001600160e01b031980821693506004831015612fc45780818460040360031b1b83161693505b505050919050565b600060208284031215612fde57600080fd5b815167ffffffffffffffff811115612ff557600080fd5b612a7084828501612c26565b600081518084526020808501808196508360051b8101915082860160005b858110156130495782840389526130378483516126a5565b9885019893509084019060010161301f565b5091979650505050505050565b60a08152600061306960a08301886126a5565b828103602084015261307b81886126a5565b9050828103604084015261308f8187613001565b90506001600160e01b03198516606084015282810360808401526130b381856126a5565b98975050505050505050565b8181038181111561035657610356612f52565b600080858511156130e257600080fd5b838611156130ef57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261311d57600080fd5b8151602061312d6124df8361252f565b82815260059290921b8401810191818101908684111561314c57600080fd5b8286015b848110156125e857805167ffffffffffffffff8111156131705760008081fd5b61317e8986838b0101612c26565b845250918301918301613150565b60006020828403121561319e57600080fd5b815167ffffffffffffffff808211156131b657600080fd5b90830190606082860312156131ca57600080fd5b6040516060810181811083821117156131e5576131e5612439565b60405282516131f381612ba4565b815260208301518281111561320757600080fd5b6132138782860161310c565b60208301525060408301518281111561322b57600080fd5b61323787828601612c26565b60408301525095945050505050565b6001600160a01b038151168252600060208201516060602085015261326e6060850182613001565b905060408301518482036040860152612f4982826126a5565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132dc57603f198886030184526132ca858351613246565b945092850192908501906001016132ae565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261331560a0850188613001565b848103606086015261332781886126a5565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561339357858303601f19018552815180516001600160e01b0319168452880151888401889052613380888501826126a5565b958901959350509087019060010161334a565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a0602082015260006133c860a0830187613001565b828103604084015261308f81876126a5565b6000826133f757634e487b7160e01b600052601260045260246000fd5b500690565b600080600080600060a0868803121561341457600080fd5b855161341f81612ba4565b602087015190955067ffffffffffffffff8082111561343d57600080fd5b61344989838a0161310c565b9550604088015191508082111561345f57600080fd5b61346b89838a01612c26565b94506060880151915061347d826123bd565b60808801519193508082111561349257600080fd5b5061349f88828901612c26565b9150509295509295909350565b6020815260006122116020830184613246565b600083516134d1818460208801612681565b8351908301906134e5818360208801612681565b01949350505050565b60006020828403121561350057600080fd5b815161221181612cda565b601f82111561355557600081815260208120601f850160051c810160208610156135325750805b601f850160051c820191505b818110156135515782815560010161353e565b5050505b505050565b815167ffffffffffffffff81111561357457613574612439565b613588816135828454612bd6565b8461350b565b602080601f8311600181146135bd57600084156135a55750858301515b600019600386901b1c1916600185901b178555613551565b600085815260208120601f198616915b828110156135ec578886015182559484019460019091019084016135cd565b508582101561360a5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220e80dfb43e469138d4ae0942cde3bd29b693f1811b97ac87db578fe698aaae86764736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { @@ -703,7 +703,7 @@ "type": "t_address" }, { - "astId": 1511, + "astId": 1537, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "batchGatewayURLs", "offset": 0, diff --git a/deployments/sepolia/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json b/deployments/sepolia/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json new file mode 100644 index 00000000..51bd8239 --- /dev/null +++ b/deployments/sepolia/solcInputs/49f758ec505ff69b72f3179ac11d7cfc.json @@ -0,0 +1,101 @@ +{ + "language": "Solidity", + "sources": { + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/registry/ENS.sol": { + "content": "pragma solidity >=0.8.4;\n\ninterface ENS {\n // Logged when the owner of a node assigns a new owner to a subnode.\n event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);\n\n // Logged when the owner of a node transfers ownership to a new account.\n event Transfer(bytes32 indexed node, address owner);\n\n // Logged when the resolver for a node changes.\n event NewResolver(bytes32 indexed node, address resolver);\n\n // Logged when the TTL of a node changes\n event NewTTL(bytes32 indexed node, uint64 ttl);\n\n // Logged when an operator is added or removed.\n event ApprovalForAll(\n address indexed owner,\n address indexed operator,\n bool approved\n );\n\n function setRecord(\n bytes32 node,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner,\n address resolver,\n uint64 ttl\n ) external;\n\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner\n ) external returns (bytes32);\n\n function setResolver(bytes32 node, address resolver) external;\n\n function setOwner(bytes32 node, address owner) external;\n\n function setTTL(bytes32 node, uint64 ttl) external;\n\n function setApprovalForAll(address operator, bool approved) external;\n\n function owner(bytes32 node) external view returns (address);\n\n function resolver(bytes32 node) external view returns (address);\n\n function ttl(bytes32 node) external view returns (uint64);\n\n function recordExists(bytes32 node) external view returns (bool);\n\n function isApprovedForAll(\n address owner,\n address operator\n ) external view returns (bool);\n}\n" + }, + "contracts/resolvers/profiles/IABIResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IABIResolver {\n event ABIChanged(bytes32 indexed node, uint256 indexed contentType);\n\n /**\n * Returns the ABI associated with an ENS node.\n * Defined in EIP205.\n * @param node The ENS node to query\n * @param contentTypes A bitwise OR of the ABI formats accepted by the caller.\n * @return contentType The content type of the return value\n * @return data The ABI data\n */\n function ABI(\n bytes32 node,\n uint256 contentTypes\n ) external view returns (uint256, bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddressResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the new (multicoin) addr function.\n */\ninterface IAddressResolver {\n event AddressChanged(\n bytes32 indexed node,\n uint256 coinType,\n bytes newAddress\n );\n\n function addr(\n bytes32 node,\n uint256 coinType\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IAddrResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\n/**\n * Interface for the legacy (ETH-only) addr function.\n */\ninterface IAddrResolver {\n event AddrChanged(bytes32 indexed node, address a);\n\n /**\n * Returns the address associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated address.\n */\n function addr(bytes32 node) external view returns (address payable);\n}\n" + }, + "contracts/resolvers/profiles/IContentHashResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IContentHashResolver {\n event ContenthashChanged(bytes32 indexed node, bytes hash);\n\n /**\n * Returns the contenthash associated with an ENS node.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function contenthash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSRecordResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSRecordResolver {\n // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.\n event DNSRecordChanged(\n bytes32 indexed node,\n bytes name,\n uint16 resource,\n bytes record\n );\n // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.\n event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);\n\n /**\n * Obtain a DNS record.\n * @param node the namehash of the node for which to fetch the record\n * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record\n * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types\n * @return the DNS record in wire format if present, otherwise empty\n */\n function dnsRecord(\n bytes32 node,\n bytes32 name,\n uint16 resource\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IDNSZoneResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDNSZoneResolver {\n // DNSZonehashChanged is emitted whenever a given node's zone hash is updated.\n event DNSZonehashChanged(\n bytes32 indexed node,\n bytes lastzonehash,\n bytes zonehash\n );\n\n /**\n * zonehash obtains the hash for the zone.\n * @param node The ENS node to query.\n * @return The associated contenthash.\n */\n function zonehash(bytes32 node) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IExtendedResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IExtendedResolver {\n function resolve(\n bytes memory name,\n bytes memory data\n ) external view returns (bytes memory);\n}\n" + }, + "contracts/resolvers/profiles/IInterfaceResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IInterfaceResolver {\n event InterfaceChanged(\n bytes32 indexed node,\n bytes4 indexed interfaceID,\n address implementer\n );\n\n /**\n * Returns the address of a contract that implements the specified interface for this name.\n * If an implementer has not been set for this interfaceID and name, the resolver will query\n * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that\n * contract implements EIP165 and returns `true` for the specified interfaceID, its address\n * will be returned.\n * @param node The ENS node to query.\n * @param interfaceID The EIP 165 interface ID to check for.\n * @return The address that implements this interface, or 0 if the interface is unsupported.\n */\n function interfaceImplementer(\n bytes32 node,\n bytes4 interfaceID\n ) external view returns (address);\n}\n" + }, + "contracts/resolvers/profiles/INameResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface INameResolver {\n event NameChanged(bytes32 indexed node, string name);\n\n /**\n * Returns the name associated with an ENS node, for reverse records.\n * Defined in EIP181.\n * @param node The ENS node to query.\n * @return The associated name.\n */\n function name(bytes32 node) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/profiles/IPubkeyResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IPubkeyResolver {\n event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);\n\n /**\n * Returns the SECP256k1 public key associated with an ENS node.\n * Defined in EIP 619.\n * @param node The ENS node to query\n * @return x The X coordinate of the curve point for the public key.\n * @return y The Y coordinate of the curve point for the public key.\n */\n function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);\n}\n" + }, + "contracts/resolvers/profiles/ITextResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface ITextResolver {\n event TextChanged(\n bytes32 indexed node,\n string indexed indexedKey,\n string key,\n string value\n );\n\n /**\n * Returns the text data associated with an ENS node and key.\n * @param node The ENS node to query.\n * @param key The text data key to query.\n * @return The associated text data.\n */\n function text(\n bytes32 node,\n string calldata key\n ) external view returns (string memory);\n}\n" + }, + "contracts/resolvers/Resolver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"./profiles/IABIResolver.sol\";\nimport \"./profiles/IAddressResolver.sol\";\nimport \"./profiles/IAddrResolver.sol\";\nimport \"./profiles/IContentHashResolver.sol\";\nimport \"./profiles/IDNSRecordResolver.sol\";\nimport \"./profiles/IDNSZoneResolver.sol\";\nimport \"./profiles/IInterfaceResolver.sol\";\nimport \"./profiles/INameResolver.sol\";\nimport \"./profiles/IPubkeyResolver.sol\";\nimport \"./profiles/ITextResolver.sol\";\nimport \"./profiles/IExtendedResolver.sol\";\n\n/**\n * A generic resolver interface which includes all the functions including the ones deprecated\n */\ninterface Resolver is\n IERC165,\n IABIResolver,\n IAddressResolver,\n IAddrResolver,\n IContentHashResolver,\n IDNSRecordResolver,\n IDNSZoneResolver,\n IInterfaceResolver,\n INameResolver,\n IPubkeyResolver,\n ITextResolver,\n IExtendedResolver\n{\n /* Deprecated events */\n event ContentChanged(bytes32 indexed node, bytes32 hash);\n\n function setApprovalForAll(address, bool) external;\n\n function approve(bytes32 node, address delegate, bool approved) external;\n\n function isApprovedForAll(address account, address operator) external;\n\n function isApprovedFor(\n address owner,\n bytes32 node,\n address delegate\n ) external;\n\n function setABI(\n bytes32 node,\n uint256 contentType,\n bytes calldata data\n ) external;\n\n function setAddr(bytes32 node, address addr) external;\n\n function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;\n\n function setContenthash(bytes32 node, bytes calldata hash) external;\n\n function setDnsrr(bytes32 node, bytes calldata data) external;\n\n function setName(bytes32 node, string calldata _name) external;\n\n function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;\n\n function setText(\n bytes32 node,\n string calldata key,\n string calldata value\n ) external;\n\n function setInterface(\n bytes32 node,\n bytes4 interfaceID,\n address implementer\n ) external;\n\n function multicall(\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n function multicallWithNodeCheck(\n bytes32 nodehash,\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n /* Deprecated functions */\n function content(bytes32 node) external view returns (bytes32);\n\n function multihash(bytes32 node) external view returns (bytes memory);\n\n function setContent(bytes32 node, bytes32 hash) external;\n\n function setMultihash(bytes32 node, bytes calldata hash) external;\n}\n" + }, + "contracts/utils/HexUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nlibrary HexUtils {\n /**\n * @dev Attempts to parse bytes32 from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexStringToBytes32(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (bytes32 r, bool valid) {\n uint256 hexLength = lastIdx - idx;\n if ((hexLength != 64 && hexLength != 40) || hexLength % 2 == 1) {\n revert(\"Invalid string length\");\n }\n valid = true;\n assembly {\n // check that the index to read to is not past the end of the string\n if gt(lastIdx, mload(str)) {\n revert(0, 0)\n }\n\n function getHex(c) -> ascii {\n // chars 48-57: 0-9\n if and(gt(c, 47), lt(c, 58)) {\n ascii := sub(c, 48)\n leave\n }\n // chars 65-70: A-F\n if and(gt(c, 64), lt(c, 71)) {\n ascii := add(sub(c, 65), 10)\n leave\n }\n // chars 97-102: a-f\n if and(gt(c, 96), lt(c, 103)) {\n ascii := add(sub(c, 97), 10)\n leave\n }\n // invalid char\n ascii := 0xff\n }\n\n let ptr := add(str, 32)\n for {\n let i := idx\n } lt(i, lastIdx) {\n i := add(i, 2)\n } {\n let byte1 := getHex(byte(0, mload(add(ptr, i))))\n let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))\n // if either byte is invalid, set invalid and break loop\n if or(eq(byte1, 0xff), eq(byte2, 0xff)) {\n valid := false\n break\n }\n let combined := or(shl(4, byte1), byte2)\n r := or(shl(8, r), combined)\n }\n }\n }\n\n /**\n * @dev Attempts to parse an address from a hex string\n * @param str The string to parse\n * @param idx The offset to start parsing at\n * @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.\n */\n function hexToAddress(\n bytes memory str,\n uint256 idx,\n uint256 lastIdx\n ) internal pure returns (address, bool) {\n if (lastIdx - idx < 40) return (address(0x0), false);\n (bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);\n return (address(uint160(uint256(r))), valid);\n }\n}\n" + }, + "contracts/utils/LowLevelCallUtils.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.13;\n\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\n\nlibrary LowLevelCallUtils {\n using Address for address;\n\n /**\n * @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data\n ) internal view returns (bool success) {\n return functionStaticCall(target, data, gasleft());\n }\n\n /**\n * @dev Makes a static call to the specified `target` with `data` using `gasLimit`. Return data can be fetched with\n * `returnDataSize` and `readReturnData`.\n * @param target The address to staticcall.\n * @param data The data to pass to the call.\n * @param gasLimit The gas limit to use for the call.\n * @return success True if the call succeeded, or false if it reverts.\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n uint256 gasLimit\n ) internal view returns (bool success) {\n require(\n target.isContract(),\n \"LowLevelCallUtils: static call to non-contract\"\n );\n assembly {\n success := staticcall(\n gasLimit,\n target,\n add(data, 32),\n mload(data),\n 0,\n 0\n )\n }\n }\n\n /**\n * @dev Returns the size of the return data of the most recent external call.\n */\n function returnDataSize() internal pure returns (uint256 len) {\n assembly {\n len := returndatasize()\n }\n }\n\n /**\n * @dev Reads return data from the most recent external call.\n * @param offset Offset into the return data.\n * @param length Number of bytes to return.\n */\n function readReturnData(\n uint256 offset,\n uint256 length\n ) internal pure returns (bytes memory data) {\n data = new bytes(length);\n assembly {\n returndatacopy(add(data, 32), offset, length)\n }\n }\n\n /**\n * @dev Reverts with the return data from the most recent external call.\n */\n function propagateRevert() internal pure {\n assembly {\n returndatacopy(0, 0, returndatasize())\n revert(0, returndatasize())\n }\n }\n}\n" + }, + "contracts/utils/NameEncoder.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.13;\n\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\n\nlibrary NameEncoder {\n using BytesUtils for bytes;\n\n function dnsEncodeName(\n string memory name\n ) internal pure returns (bytes memory dnsName, bytes32 node) {\n uint8 labelLength = 0;\n bytes memory bytesName = bytes(name);\n uint256 length = bytesName.length;\n dnsName = new bytes(length + 2);\n node = 0;\n if (length == 0) {\n dnsName[0] = 0;\n return (dnsName, node);\n }\n\n // use unchecked to save gas since we check for an underflow\n // and we check for the length before the loop\n unchecked {\n for (uint256 i = length - 1; i >= 0; i--) {\n if (bytesName[i] == \".\") {\n dnsName[i + 1] = bytes1(labelLength);\n node = keccak256(\n abi.encodePacked(\n node,\n bytesName.keccak(i + 1, labelLength)\n )\n );\n labelLength = 0;\n } else {\n labelLength += 1;\n dnsName[i + 1] = bytesName[i];\n }\n if (i == 0) {\n break;\n }\n }\n }\n\n node = keccak256(\n abi.encodePacked(node, bytesName.keccak(0, labelLength))\n );\n\n dnsName[0] = bytes1(labelLength);\n return (dnsName, node);\n }\n}\n" + }, + "contracts/utils/UniversalResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.17 <0.9.0;\n\nimport {ERC165} from \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {LowLevelCallUtils} from \"./LowLevelCallUtils.sol\";\nimport {ENS} from \"../registry/ENS.sol\";\nimport {IExtendedResolver} from \"../resolvers/profiles/IExtendedResolver.sol\";\nimport {Resolver, INameResolver, IAddrResolver} from \"../resolvers/Resolver.sol\";\nimport {NameEncoder} from \"./NameEncoder.sol\";\nimport {BytesUtils} from \"../wrapper/BytesUtils.sol\";\nimport {HexUtils} from \"./HexUtils.sol\";\n\nerror OffchainLookup(\n address sender,\n string[] urls,\n bytes callData,\n bytes4 callbackFunction,\n bytes extraData\n);\n\nerror ResolverNotFound();\n\nerror ResolverWildcardNotSupported();\n\nerror ResolverNotContract();\n\nerror ResolverError(bytes returnData);\n\nerror HttpError(HttpErrorItem[] errors);\n\nstruct HttpErrorItem {\n uint16 status;\n string message;\n}\n\nstruct MulticallData {\n bytes name;\n bytes[] data;\n string[] gateways;\n bytes4 callbackFunction;\n bool isWildcard;\n address resolver;\n bytes metaData;\n bool[] failures;\n}\n\nstruct MulticallChecks {\n bool isCallback;\n bool hasExtendedResolver;\n}\n\nstruct OffchainLookupCallData {\n address sender;\n string[] urls;\n bytes callData;\n}\n\nstruct OffchainLookupExtraData {\n bytes4 callbackFunction;\n bytes data;\n}\n\nstruct Result {\n bool success;\n bytes returnData;\n}\n\ninterface BatchGateway {\n function query(\n OffchainLookupCallData[] memory data\n ) external returns (bool[] memory failures, bytes[] memory responses);\n}\n\n/**\n * The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,\n * making it possible to make a single smart contract call to resolve an ENS name.\n */\ncontract UniversalResolver is ERC165, Ownable {\n using Address for address;\n using NameEncoder for string;\n using BytesUtils for bytes;\n using HexUtils for bytes;\n\n string[] public batchGatewayURLs;\n ENS public immutable registry;\n\n constructor(address _registry, string[] memory _urls) {\n registry = ENS(_registry);\n batchGatewayURLs = _urls;\n }\n\n function setGatewayURLs(string[] memory _urls) public onlyOwner {\n batchGatewayURLs = _urls;\n }\n\n /**\n * @dev Performs ENS name resolution for the supplied name and resolution data.\n * @param name The name to resolve, in normalised and DNS-encoded form.\n * @param data The resolution data, as specified in ENSIP-10.\n * @return The result of resolving the name.\n */\n function resolve(\n bytes calldata name,\n bytes memory data\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n batchGatewayURLs,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data\n ) external view returns (Result[] memory, address) {\n return resolve(name, data, batchGatewayURLs);\n }\n\n function resolve(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways\n ) external view returns (bytes memory, address) {\n return\n _resolveSingle(\n name,\n data,\n gateways,\n this.resolveSingleCallback.selector,\n \"\"\n );\n }\n\n function resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways\n ) public view returns (Result[] memory, address) {\n return\n _resolve(name, data, gateways, this.resolveCallback.selector, \"\");\n }\n\n function _resolveSingle(\n bytes calldata name,\n bytes memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) public view returns (bytes memory, address) {\n bytes[] memory dataArr = new bytes[](1);\n dataArr[0] = data;\n (Result[] memory results, address resolver) = _resolve(\n name,\n dataArr,\n gateways,\n callbackFunction,\n metaData\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function _resolve(\n bytes calldata name,\n bytes[] memory data,\n string[] memory gateways,\n bytes4 callbackFunction,\n bytes memory metaData\n ) internal view returns (Result[] memory results, address resolverAddress) {\n (Resolver resolver, , uint256 finalOffset) = findResolver(name);\n resolverAddress = address(resolver);\n if (resolverAddress == address(0)) {\n revert ResolverNotFound();\n }\n\n if (!resolverAddress.isContract()) {\n revert ResolverNotContract();\n }\n\n bool isWildcard = finalOffset != 0;\n\n results = _multicall(\n MulticallData(\n name,\n data,\n gateways,\n callbackFunction,\n isWildcard,\n resolverAddress,\n metaData,\n new bool[](data.length)\n )\n );\n }\n\n function reverse(\n bytes calldata reverseName\n ) external view returns (string memory, address, address, address) {\n return reverse(reverseName, batchGatewayURLs);\n }\n\n /**\n * @dev Performs ENS name reverse resolution for the supplied reverse name.\n * @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse\n * @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.\n */\n function reverse(\n bytes calldata reverseName,\n string[] memory gateways\n ) public view returns (string memory, address, address, address) {\n bytes memory encodedCall = abi.encodeCall(\n INameResolver.name,\n reverseName.namehash(0)\n );\n (\n bytes memory reverseResolvedData,\n address reverseResolverAddress\n ) = _resolveSingle(\n reverseName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n \"\"\n );\n\n return\n getForwardDataFromReverse(\n reverseResolvedData,\n reverseResolverAddress,\n gateways\n );\n }\n\n function getForwardDataFromReverse(\n bytes memory resolvedReverseData,\n address reverseResolverAddress,\n string[] memory gateways\n ) internal view returns (string memory, address, address, address) {\n string memory resolvedName = abi.decode(resolvedReverseData, (string));\n\n (bytes memory encodedName, bytes32 namehash) = resolvedName\n .dnsEncodeName();\n\n bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);\n bytes memory metaData = abi.encode(\n resolvedName,\n reverseResolverAddress\n );\n (bytes memory resolvedData, address resolverAddress) = this\n ._resolveSingle(\n encodedName,\n encodedCall,\n gateways,\n this.reverseCallback.selector,\n metaData\n );\n\n address resolvedAddress = abi.decode(resolvedData, (address));\n\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n function resolveSingleCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (bytes memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveSingleCallback.selector\n );\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n return (result.returnData, resolver);\n }\n\n function resolveCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (Result[] memory, address) {\n (Result[] memory results, address resolver, , ) = _resolveCallback(\n response,\n extraData,\n this.resolveCallback.selector\n );\n return (results, resolver);\n }\n\n function reverseCallback(\n bytes calldata response,\n bytes calldata extraData\n ) external view returns (string memory, address, address, address) {\n (\n Result[] memory results,\n address resolverAddress,\n string[] memory gateways,\n bytes memory metaData\n ) = _resolveCallback(\n response,\n extraData,\n this.reverseCallback.selector\n );\n\n Result memory result = results[0];\n\n _checkResolveSingle(result);\n\n if (metaData.length > 0) {\n (string memory resolvedName, address reverseResolverAddress) = abi\n .decode(metaData, (string, address));\n address resolvedAddress = abi.decode(result.returnData, (address));\n return (\n resolvedName,\n resolvedAddress,\n reverseResolverAddress,\n resolverAddress\n );\n }\n\n return\n getForwardDataFromReverse(\n result.returnData,\n resolverAddress,\n gateways\n );\n }\n\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override returns (bool) {\n return\n interfaceId == type(IExtendedResolver).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n function _resolveCallback(\n bytes calldata response,\n bytes calldata extraData,\n bytes4 callbackFunction\n )\n internal\n view\n returns (Result[] memory, address, string[] memory, bytes memory)\n {\n MulticallData memory multicallData;\n multicallData.callbackFunction = callbackFunction;\n (bool[] memory failures, bytes[] memory responses) = abi.decode(\n response,\n (bool[], bytes[])\n );\n OffchainLookupExtraData[] memory extraDatas;\n (\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n ) = abi.decode(\n extraData,\n (bool, address, string[], bytes, OffchainLookupExtraData[])\n );\n require(responses.length <= extraDatas.length);\n multicallData.data = new bytes[](extraDatas.length);\n multicallData.failures = new bool[](extraDatas.length);\n uint256 offchainCount = 0;\n for (uint256 i = 0; i < extraDatas.length; i++) {\n if (extraDatas[i].callbackFunction == bytes4(0)) {\n // This call did not require an offchain lookup; use the previous input data.\n multicallData.data[i] = extraDatas[i].data;\n } else {\n if (failures[offchainCount]) {\n multicallData.failures[i] = true;\n multicallData.data[i] = responses[offchainCount];\n } else {\n multicallData.data[i] = abi.encodeWithSelector(\n extraDatas[i].callbackFunction,\n responses[offchainCount],\n extraDatas[i].data\n );\n }\n offchainCount = offchainCount + 1;\n }\n }\n\n return (\n _multicall(multicallData),\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData\n );\n }\n\n /**\n * @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps\n * the error with the data necessary to continue the request where it left off.\n * @param target The address to call.\n * @param data The data to call `target` with.\n * @return offchain Whether the call reverted with an `OffchainLookup` error.\n * @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.\n * @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.\n * @return result Whether the call succeeded.\n */\n function callWithOffchainLookupPropagation(\n address target,\n bytes memory data,\n bool isSafe\n )\n internal\n view\n returns (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool result\n )\n {\n if (isSafe) {\n result = LowLevelCallUtils.functionStaticCall(target, data);\n } else {\n result = LowLevelCallUtils.functionStaticCall(target, data, 50000);\n }\n uint256 size = LowLevelCallUtils.returnDataSize();\n\n if (result) {\n return (\n false,\n LowLevelCallUtils.readReturnData(0, size),\n extraData,\n true\n );\n }\n\n // Failure\n if (size >= 4) {\n bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);\n // Offchain lookup. Decode the revert message and create our own that nests it.\n bytes memory revertData = LowLevelCallUtils.readReturnData(\n 4,\n size - 4\n );\n if (bytes4(errorId) == OffchainLookup.selector) {\n (\n address wrappedSender,\n string[] memory wrappedUrls,\n bytes memory wrappedCallData,\n bytes4 wrappedCallbackFunction,\n bytes memory wrappedExtraData\n ) = abi.decode(\n revertData,\n (address, string[], bytes, bytes4, bytes)\n );\n if (wrappedSender == target) {\n returnData = abi.encode(\n OffchainLookupCallData(\n wrappedSender,\n wrappedUrls,\n wrappedCallData\n )\n );\n extraData = OffchainLookupExtraData(\n wrappedCallbackFunction,\n wrappedExtraData\n );\n return (true, returnData, extraData, false);\n }\n } else {\n returnData = bytes.concat(errorId, revertData);\n return (false, returnData, extraData, false);\n }\n }\n }\n\n /**\n * @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively\n * removing labels until it finds a result.\n * @param name The name to resolve, in DNS-encoded and normalised form.\n * @return resolver The Resolver responsible for this name.\n * @return namehash The namehash of the full name.\n * @return finalOffset The offset of the first label with a resolver.\n */\n function findResolver(\n bytes calldata name\n ) public view returns (Resolver, bytes32, uint256) {\n (\n address resolver,\n bytes32 namehash,\n uint256 finalOffset\n ) = findResolver(name, 0);\n return (Resolver(resolver), namehash, finalOffset);\n }\n\n function findResolver(\n bytes calldata name,\n uint256 offset\n ) internal view returns (address, bytes32, uint256) {\n uint256 labelLength = uint256(uint8(name[offset]));\n if (labelLength == 0) {\n return (address(0), bytes32(0), offset);\n }\n uint256 nextLabel = offset + labelLength + 1;\n bytes32 labelHash;\n if (\n labelLength == 66 &&\n // 0x5b == '['\n name[offset + 1] == 0x5b &&\n // 0x5d == ']'\n name[nextLabel - 1] == 0x5d\n ) {\n // Encrypted label\n (labelHash, ) = bytes(name[offset + 2:nextLabel - 1])\n .hexStringToBytes32(0, 64);\n } else {\n labelHash = keccak256(name[offset + 1:nextLabel]);\n }\n (\n address parentresolver,\n bytes32 parentnode,\n uint256 parentoffset\n ) = findResolver(name, nextLabel);\n bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));\n address resolver = registry.resolver(node);\n if (resolver != address(0)) {\n return (resolver, node, offset);\n }\n return (parentresolver, node, parentoffset);\n }\n\n function _checkInterface(\n address resolver,\n bytes4 interfaceId\n ) internal view returns (bool) {\n try\n Resolver(resolver).supportsInterface{gas: 50000}(interfaceId)\n returns (bool supported) {\n return supported;\n } catch {\n return false;\n }\n }\n\n function _checkSafetyAndItem(\n bytes memory name,\n bytes memory item,\n address resolver,\n MulticallChecks memory multicallChecks\n ) internal view returns (bool, bytes memory) {\n if (!multicallChecks.isCallback) {\n if (multicallChecks.hasExtendedResolver) {\n return (\n true,\n abi.encodeCall(IExtendedResolver.resolve, (name, item))\n );\n }\n return (_checkInterface(resolver, bytes4(item)), item);\n }\n return (true, item);\n }\n\n function _checkMulticall(\n MulticallData memory multicallData\n ) internal view returns (MulticallChecks memory) {\n bool isCallback = multicallData.name.length == 0;\n bool hasExtendedResolver = _checkInterface(\n multicallData.resolver,\n type(IExtendedResolver).interfaceId\n );\n\n if (multicallData.isWildcard && !hasExtendedResolver) {\n revert ResolverWildcardNotSupported();\n }\n\n return MulticallChecks(isCallback, hasExtendedResolver);\n }\n\n function _checkResolveSingle(Result memory result) internal pure {\n if (!result.success) {\n if (bytes4(result.returnData) == HttpError.selector) {\n bytes memory returnData = result.returnData;\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n revert ResolverError(result.returnData);\n }\n }\n\n function _multicall(\n MulticallData memory multicallData\n ) internal view returns (Result[] memory results) {\n uint256 length = multicallData.data.length;\n uint256 offchainCount = 0;\n OffchainLookupCallData[]\n memory callDatas = new OffchainLookupCallData[](length);\n OffchainLookupExtraData[]\n memory extraDatas = new OffchainLookupExtraData[](length);\n results = new Result[](length);\n MulticallChecks memory multicallChecks = _checkMulticall(multicallData);\n\n for (uint256 i = 0; i < length; i++) {\n bytes memory item = multicallData.data[i];\n bool failure = multicallData.failures[i];\n\n if (failure) {\n results[i] = Result(false, item);\n continue;\n }\n\n bool isSafe = false;\n (isSafe, item) = _checkSafetyAndItem(\n multicallData.name,\n item,\n multicallData.resolver,\n multicallChecks\n );\n\n (\n bool offchain,\n bytes memory returnData,\n OffchainLookupExtraData memory extraData,\n bool success\n ) = callWithOffchainLookupPropagation(\n multicallData.resolver,\n item,\n isSafe\n );\n\n if (offchain) {\n callDatas[offchainCount] = abi.decode(\n returnData,\n (OffchainLookupCallData)\n );\n extraDatas[i] = extraData;\n offchainCount += 1;\n continue;\n }\n\n if (success && multicallChecks.hasExtendedResolver) {\n // if this is a successful resolve() call, unwrap the result\n returnData = abi.decode(returnData, (bytes));\n }\n results[i] = Result(success, returnData);\n extraDatas[i].data = item;\n }\n\n if (offchainCount == 0) {\n return results;\n }\n\n // Trim callDatas if offchain data exists\n assembly {\n mstore(callDatas, offchainCount)\n }\n\n revert OffchainLookup(\n address(this),\n multicallData.gateways,\n abi.encodeWithSelector(BatchGateway.query.selector, callDatas),\n multicallData.callbackFunction,\n abi.encode(\n multicallData.isWildcard,\n multicallData.resolver,\n multicallData.gateways,\n multicallData.metaData,\n extraDatas\n )\n );\n }\n}\n" + }, + "contracts/wrapper/BytesUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nlibrary BytesUtils {\n /*\n * @dev Returns the keccak-256 hash of a byte range.\n * @param self The byte string to hash.\n * @param offset The position to start hashing at.\n * @param len The number of bytes to hash.\n * @return The hash of the byte range.\n */\n function keccak(\n bytes memory self,\n uint256 offset,\n uint256 len\n ) internal pure returns (bytes32 ret) {\n require(offset + len <= self.length);\n assembly {\n ret := keccak256(add(add(self, 32), offset), len)\n }\n }\n\n /**\n * @dev Returns the ENS namehash of a DNS-encoded name.\n * @param self The DNS-encoded name to hash.\n * @param offset The offset at which to start hashing.\n * @return The namehash of the name.\n */\n function namehash(\n bytes memory self,\n uint256 offset\n ) internal pure returns (bytes32) {\n (bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);\n if (labelhash == bytes32(0)) {\n require(offset == self.length - 1, \"namehash: Junk at end of name\");\n return bytes32(0);\n }\n return\n keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));\n }\n\n /**\n * @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.\n * @param self The byte string to read a label from.\n * @param idx The index to read a label at.\n * @return labelhash The hash of the label at the specified index, or 0 if it is the last label.\n * @return newIdx The index of the start of the next label.\n */\n function readLabel(\n bytes memory self,\n uint256 idx\n ) internal pure returns (bytes32 labelhash, uint256 newIdx) {\n require(idx < self.length, \"readLabel: Index out of bounds\");\n uint256 len = uint256(uint8(self[idx]));\n if (len > 0) {\n labelhash = keccak(self, idx + 1, len);\n } else {\n labelhash = bytes32(0);\n }\n newIdx = idx + len + 1;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index dd181269..1ef1119c 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "format": "prettier --write .", "prepublishOnly": "yarn build", "pub": "yarn publish --access public", - "prepare": "husky install" + "prepare": "husky install", + "wikiCheck": "node wikiCheck.js " }, "files": [ "build", diff --git a/test/utils/TestUniversalResolver.js b/test/utils/TestUniversalResolver.js index ece83114..c805ecfe 100644 --- a/test/utils/TestUniversalResolver.js +++ b/test/utils/TestUniversalResolver.js @@ -1,7 +1,7 @@ const { solidity } = require('ethereum-waffle') const { use, expect } = require('chai') const namehash = require('eth-ens-namehash') -const { hexDataSlice } = require('ethers/lib/utils') +const { hexDataSlice, concat } = require('ethers/lib/utils') const sha3 = require('web3-utils').sha3 const { Contract } = require('ethers') const { ethers } = require('hardhat') @@ -194,6 +194,12 @@ contract('UniversalResolver', function (accounts) { 4, ) + const resolveSig = ethers.utils.hexDataSlice( + ethers.utils.id('resolve(bytes,bytes)'), + 0, + 4, + ) + describe('findResolver()', () => { it('should find an exact match resolver', async () => { const result = await universalResolver.findResolver( @@ -451,6 +457,63 @@ contract('UniversalResolver', function (accounts) { } }) + it('should return a wrapped revert with resolve() wrapped calls in extraData when combining onchain and offchain lookups', async () => { + const addrData = publicResolver.interface.encodeFunctionData( + 'addr(bytes32)', + [namehash.hash('offchain.test.eth')], + ) + const onchainDataCall = '0x12345678' + + try { + await universalResolver['resolve(bytes,bytes[])']( + dns.hexEncodeName('offchain.test.eth'), + [addrData, onchainDataCall], + ) + expect(false).to.be.true + } catch (e) { + expect(e.errorName).to.equal('OffchainLookup') + expect(e.errorArgs.sender).to.equal(universalResolver.address) + expect(e.errorArgs.urls).to.deep.equal([ + 'http://universal-offchain-resolver.local/', + ]) + const decodedCallData = batchGateway.decodeFunctionData( + 'query', + e.errorArgs.callData, + ) + expect(decodedCallData).to.deep.equal([ + [[dummyOffchainResolver.address, ['https://example.com/'], addrData]], + ]) + expect(e.errorArgs.callbackFunction).to.equal( + ethers.utils.hexDataSlice( + ethers.utils.id('resolveCallback(bytes,bytes)'), + 0, + 4, + ), + ) + const decodedExtraData = ethers.utils.defaultAbiCoder.decode( + ['bool', 'address', 'string[]', 'bytes', '(bytes4,bytes)[]'], + e.errorArgs.extraData, + ) + expect(decodedExtraData).to.deep.equal([ + false, + dummyOffchainResolver.address, + ['http://universal-offchain-resolver.local/'], + '0x', + [ + [resolveCallbackSig, addrData], + [ + '0x00000000', + // just using the UR interface for ensip10 + universalResolver.interface.encodeFunctionData( + 'resolve(bytes,bytes)', + [dns.hexEncodeName('offchain.test.eth'), onchainDataCall], + ), + ], + ], + ]) + } + }) + describe('batch', () => { it('should resolve multiple records onchain', async () => { const textData = publicResolver.interface.encodeFunctionData( @@ -515,7 +578,24 @@ contract('UniversalResolver', function (accounts) { expect(false).to.be.true } catch (e) { expect(e.errorName).to.equal('OffchainLookup') - expect(e.errorArgs.callData).to.equal(callData) + const decodedCallData = batchGateway.decodeFunctionData( + 'query', + e.errorArgs.callData, + ) + expect(decodedCallData).to.deep.equal([ + [ + [ + dummyOffchainResolver.address, + ['https://example.com/'], + textData, + ], + [ + dummyOffchainResolver.address, + ['https://example.com/'], + addrData, + ], + ], + ]) expect(e.errorArgs.callbackFunction).to.equal(resolveCallbackSig) expect(e.errorArgs.extraData).to.equal(extraData) } @@ -661,9 +741,9 @@ contract('UniversalResolver', function (accounts) { expect(encodedRes.returnData).to.equal('0x') }) it('should allow response at non-0 extraData index', async () => { - const addrData = publicResolver.interface.encodeFunctionData( - 'addr(bytes32)', - [namehash.hash('offchain.test.eth')], + const onchainCall = universalResolver.interface.encodeFunctionData( + 'resolve(bytes,bytes)', + [dns.hexEncodeName('offchain.test.eth'), '0x12345678'], ) const textData = publicResolver.interface.encodeFunctionData( 'text(bytes32,string)', @@ -677,7 +757,7 @@ contract('UniversalResolver', function (accounts) { ['http://universal-offchain-resolver.local/'], '0x', [ - ['0x00000000', addrData], + ['0x00000000', onchainCall], [resolveCallbackSig, textData], ], ], @@ -690,7 +770,7 @@ contract('UniversalResolver', function (accounts) { await universalResolver.callStatic.resolveCallback(responses, extraData) expect(encodedRes.success).to.equal(true) expect(encodedResTwo.success).to.equal(true) - const [addrRet] = ethers.utils.defaultAbiCoder.decode( + const [fooString] = ethers.utils.defaultAbiCoder.decode( ['bytes'], encodedRes.returnData, ) @@ -698,7 +778,7 @@ contract('UniversalResolver', function (accounts) { 'addr(bytes32)', encodedResTwo.returnData, ) - expect(ethers.utils.toUtf8String(addrRet)).to.equal('onchain') + expect(ethers.utils.toUtf8String(fooString)).to.equal('foo') expect(addrRetTwo).to.equal(dummyOffchainResolver.address) expect(resolverAddress).to.equal(dummyOffchainResolver.address) }) @@ -801,6 +881,45 @@ contract('UniversalResolver', function (accounts) { expect(a2).to.equal(dummyOffchainResolver.address) expect(a3).to.equal(dummyOffchainResolver.address) }) + it('should propagate HttpError', async () => { + const urWithHttpErrorAbi = new ethers.Contract( + universalResolver.address, + [ + ...universalResolver.interface.fragments, + 'error HttpError((uint16,string)[])', + ], + ethers.provider, + ) + const errorData = urWithHttpErrorAbi.interface.encodeErrorResult( + 'HttpError', + [[[404, 'Not Found']]], + ) + const extraData = ethers.utils.defaultAbiCoder.encode( + ['bool', 'address', 'string[]', 'bytes', '(bytes4,bytes)[]'], + [ + false, + dummyOffchainResolver.address, + ['http://universal-offchain-resolver.local/'], + '0x', + [[resolveCallbackSig, errorData]], + ], + ) + const responses = batchGateway.encodeFunctionResult('query', [ + [true], + [errorData], + ]) + + try { + await urWithHttpErrorAbi.callStatic.reverseCallback( + responses, + extraData, + ) + expect(false).to.be.true + } catch (e) { + expect(e.errorName).to.equal('HttpError') + expect(e.errorArgs).to.deep.equal([[[404, 'Not Found']]]) + } + }) }) describe('reverse()', () => { diff --git a/test/utils/mocks/DummyOffchainResolver.sol b/test/utils/mocks/DummyOffchainResolver.sol index 220406f8..83780967 100644 --- a/test/utils/mocks/DummyOffchainResolver.sol +++ b/test/utils/mocks/DummyOffchainResolver.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.4; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import "../../../contracts/resolvers/profiles/ITextResolver.sol"; import "../../../contracts/resolvers/profiles/IExtendedResolver.sol"; error OffchainLookup( @@ -27,6 +28,10 @@ contract DummyOffchainResolver is IExtendedResolver, ERC165 { ) external view returns (bytes memory) { string[] memory urls = new string[](1); urls[0] = "https://example.com/"; + + if (bytes4(data) == bytes4(0x12345678)) { + return abi.encode("foo"); + } revert OffchainLookup( address(this), urls, @@ -36,8 +41,8 @@ contract DummyOffchainResolver is IExtendedResolver, ERC165 { ); } - function addr(bytes32) external pure returns (bytes memory) { - return abi.encode("onchain"); + function addr(bytes32) external pure returns (address) { + return 0x69420f05A11f617B4B74fFe2E04B2D300dFA556F; } function resolveCallback( diff --git a/wikiCheck.js b/wikiCheck.js new file mode 100644 index 00000000..3193bfb8 --- /dev/null +++ b/wikiCheck.js @@ -0,0 +1,130 @@ +const https = require('https') +const fs = require('fs') +const path = require('path') + +const SUPPORTED_CHAINS = ['mainnet', 'sepolia', 'holesky'] +//Updates to the wiki take 5 minutes to show up on this URL +const WIKI_DEPLOYMENTS_URL = + 'https://raw.githubusercontent.com/wiki/ensdomains/ens-contracts/ENS-Contract-Deployments.md' + +const getRawWikiData = (url) => { + return new Promise((resolve, reject) => { + https.get(url, (res) => { + let data = '' + + res.on('data', (chunk) => { + data += chunk + }) + + res.on('end', () => { + resolve(data) + }) + + res.on('error', (err) => { + reject(err) + }) + }) + }) +} + +const getChainDeploymentsFromWiki = (chainIndex, lines) => { + const chainName = SUPPORTED_CHAINS[chainIndex] + const indexOfChain = lines.findIndex((line) => line.includes(chainName)) + const indexOfNextChain = lines.findIndex( + (line, index) => index > indexOfChain && line.includes('#'), + ) + const startOfChainDeployments = indexOfChain + 3 + + if (indexOfNextChain === -1) { + //If no next chain, then we are at the end of the file + const chainDeployments = lines.slice(startOfChainDeployments, lines.length) + return chainDeployments + } + + const chainDeployments = lines.slice( + startOfChainDeployments, + indexOfNextChain, + ) + return chainDeployments +} + +const checkDeployment = ( + chainName, + deploymentFilenames, + wikiDeployments, + i, +) => { + const deploymentFilename = deploymentFilenames[i] + + const wikiDeploymentString = wikiDeployments.find((wikiDeployment) => { + const wikiDeploymentName = wikiDeployment.split('|')[1].trim() + + const match = wikiDeploymentName.match( + new RegExp(`${deploymentFilename.split('.')[0].trim()}`), + ) + return match && match?.[0] === match?.input + }) + + const wikiDeploymentAddress = wikiDeploymentString.substring( + wikiDeploymentString.indexOf('[') + 1, + wikiDeploymentString.lastIndexOf(']'), + ) + const wikiEtherscanAddress = wikiDeploymentString.substring( + wikiDeploymentString.lastIndexOf('/') + 1, + wikiDeploymentString.lastIndexOf(')'), + ) + + const deployment = require(`./deployments/${chainName}/${deploymentFilename}`) + + if (deployment.address !== wikiDeploymentAddress) { + throw new Error( + `Deployment ${i} in wiki and in the repository do not match for ${chainName}. Wiki: ${wikiDeploymentAddress}, Deployment: ${deployment.address}`, + ) + } + + if (deployment.address !== wikiEtherscanAddress) { + throw new Error( + `Etherscan address ${i} in wiki and in the repository do not match for ${chainName}. Wiki Etherscan: ${wikiEtherscanAddress}, Deployment: ${deployment.address}`, + ) + } +} + +const checkChain = async (chainIndex, lines) => { + const chainName = SUPPORTED_CHAINS[chainIndex] + const directoryPath = path.join(__dirname, 'deployments', chainName) + + let deploymentFilenames = [] + + const files = await fs.promises.readdir(directoryPath) + const jsonFiles = files.filter( + (file) => path.extname(file).toLowerCase() === '.json', + ) + + //Don't include migrations file + deploymentFilenames = jsonFiles.slice(1) + + const wikiDeployments = getChainDeploymentsFromWiki(chainIndex, lines) + + if (wikiDeployments.length !== deploymentFilenames.length) { + throw new Error( + `Number of deployments in wiki and in the repository do not match for ${SUPPORTED_CHAINS[chainIndex]}`, + ) + } + + for (let i = 0; i < wikiDeployments.length; i++) { + checkDeployment(chainName, deploymentFilenames, wikiDeployments, i) + } +} + +const run = async () => { + const data = await getRawWikiData(WIKI_DEPLOYMENTS_URL) + const lines = data.split('\n') + + for (let i = 0; i < SUPPORTED_CHAINS.length; i++) { + await checkChain(i, lines) + } + + console.log('All deployments match') +} + +run()