From 00c31e864ad059f51c40092f84da379ac79b7a53 Mon Sep 17 00:00:00 2001 From: tate Date: Wed, 3 Jan 2024 12:24:39 +1100 Subject: [PATCH 1/4] fix: propagate httperror on single resolve correctly --- contracts/utils/UniversalResolver.sol | 9 +++---- test/utils/TestUniversalResolver.js | 39 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/contracts/utils/UniversalResolver.sol b/contracts/utils/UniversalResolver.sol index eae3d628..33e39870 100644 --- a/contracts/utils/UniversalResolver.sol +++ b/contracts/utils/UniversalResolver.sol @@ -594,11 +594,10 @@ contract UniversalResolver is ERC165, Ownable { function _checkResolveSingle(Result memory result) internal pure { if (!result.success) { if (bytes4(result.returnData) == HttpError.selector) { - (, HttpErrorItem[] memory errors) = abi.decode( - result.returnData, - (bytes4, HttpErrorItem[]) - ); - revert HttpError(errors); + bytes memory returnData = result.returnData; + assembly { + revert(add(returnData, 32), mload(returnData)) + } } revert ResolverError(result.returnData); } diff --git a/test/utils/TestUniversalResolver.js b/test/utils/TestUniversalResolver.js index 49093d16..905f51a7 100644 --- a/test/utils/TestUniversalResolver.js +++ b/test/utils/TestUniversalResolver.js @@ -560,6 +560,45 @@ contract('UniversalResolver', function (accounts) { ) expect(addrRet).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.resolveSingleCallback( + 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('resolveCallback', () => { it('should resolve records via a callback from offchain lookup', async () => { From 87a95a85ba53283d72ef33073177caab36f286a3 Mon Sep 17 00:00:00 2001 From: tate Date: Thu, 4 Jan 2024 12:24:19 +1100 Subject: [PATCH 2/4] added try...catch assertions --- test/utils/TestUniversalResolver.js | 37 +++++++++++++---------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/test/utils/TestUniversalResolver.js b/test/utils/TestUniversalResolver.js index 905f51a7..ece83114 100644 --- a/test/utils/TestUniversalResolver.js +++ b/test/utils/TestUniversalResolver.js @@ -262,15 +262,12 @@ contract('UniversalResolver', function (accounts) { [namehash.hash('no-resolver.test.other')], ) - try { - await universalResolver['resolve(bytes,bytes)']( + await expect( + universalResolver['resolve(bytes,bytes)']( dns.hexEncodeName('no-resolver.test.other'), data, - ) - expect(false).to.be.true - } catch (e) { - expect(e.errorName).to.equal('ResolverNotFound') - } + ), + ).to.be.revertedWith('ResolverNotFound') }) it('should throw if a resolver is not a contract', async () => { @@ -279,15 +276,12 @@ contract('UniversalResolver', function (accounts) { [namehash.hash('non-contract-resolver.test.eth')], ) - try { - await universalResolver['resolve(bytes,bytes)']( + await expect( + universalResolver['resolve(bytes,bytes)']( dns.hexEncodeName('non-contract-resolver.test.eth'), data, - ) - expect(false).to.be.true - } catch (e) { - expect(e.errorName).to.equal('ResolverNotContract') - } + ), + ).to.be.revertedWith('ResolverNotContract') }) it('should throw with revert data if resolver reverts', async () => { @@ -326,14 +320,12 @@ contract('UniversalResolver', function (accounts) { [namehash.hash('no-resolver.test.eth')], ) - try { - await universalResolver['resolve(bytes,bytes)']( + await expect( + universalResolver['resolve(bytes,bytes)']( dns.hexEncodeName('no-resolver.test.eth'), data, - ) - } catch (e) { - expect(e.errorName).to.equal('ResolverWildcardNotSupported') - } + ), + ).to.be.revertedWith('ResolverWildcardNotSupported') }) it('should resolve a record if `supportsInterface` throws', async () => { @@ -386,6 +378,7 @@ contract('UniversalResolver', function (accounts) { dns.hexEncodeName('test2.eth'), data, ) + expect(false).to.be.true } catch (e) { expect(e.errorName).to.equal('ResolverError') expect(e.errorSignature).to.equal('ResolverError(bytes)') @@ -421,6 +414,7 @@ contract('UniversalResolver', function (accounts) { dns.hexEncodeName('offchain.test.eth'), data, ) + expect(false).to.be.true } catch (e) { expect(e.errorName).to.equal('OffchainLookup') expect(e.errorArgs.sender).to.equal(universalResolver.address) @@ -449,6 +443,7 @@ contract('UniversalResolver', function (accounts) { data, ['https://custom-offchain-resolver.local/'], ) + expect(false).to.be.true } catch (e) { expect(e.errorArgs.urls).to.deep.equal([ 'https://custom-offchain-resolver.local/', @@ -517,6 +512,7 @@ contract('UniversalResolver', function (accounts) { dns.hexEncodeName('offchain.test.eth'), [textData, addrData], ) + expect(false).to.be.true } catch (e) { expect(e.errorName).to.equal('OffchainLookup') expect(e.errorArgs.callData).to.equal(callData) @@ -762,6 +758,7 @@ contract('UniversalResolver', function (accounts) { ]) try { await universalResolver.callStatic.reverseCallback(responses, extraData) + expect(false).to.be.true } catch (e) { expect(e.errorName).to.equal('OffchainLookup') const extraDataReturned = ethers.utils.defaultAbiCoder.decode( From b763c9a0c70545f71b9267e4c1df83ef25aa162c Mon Sep 17 00:00:00 2001 From: tate Date: Mon, 8 Jan 2024 11:44:37 +1100 Subject: [PATCH 3/4] testnets --- deployments/goerli/UniversalResolver.json | 65 ++++------- .../b8a92c9207ae2a5ea22df4d7303f97f4.json | 101 ++++++++++++++++++ deployments/sepolia/UniversalResolver.json | 65 ++++------- .../b8a92c9207ae2a5ea22df4d7303f97f4.json | 101 ++++++++++++++++++ 4 files changed, 244 insertions(+), 88 deletions(-) create mode 100644 deployments/goerli/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json create mode 100644 deployments/sepolia/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json diff --git a/deployments/goerli/UniversalResolver.json b/deployments/goerli/UniversalResolver.json index 0a9cc3f4..575bb5e5 100644 --- a/deployments/goerli/UniversalResolver.json +++ b/deployments/goerli/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0xaac727b9451268d7779F699dbaF6c2eAE571C369", + "address": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", "abi": [ { "inputs": [ @@ -17,29 +17,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint16", - "name": "status", - "type": "uint16" - }, - { - "internalType": "string", - "name": "message", - "type": "string" - } - ], - "internalType": "struct HttpErrorItem[]", - "name": "errors", - "type": "tuple[]" - } - ], - "name": "HttpError", - "type": "error" - }, { "inputs": [ { @@ -619,34 +596,34 @@ "type": "function" } ], - "transactionHash": "0x158efb24a1e0725ddea8fa9f2c637a63d25a9b86db2c75dd83ff4da979a3192e", + "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", "receipt": { "to": null, "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", - "contractAddress": "0xaac727b9451268d7779F699dbaF6c2eAE571C369", - "transactionIndex": 44, - "gasUsed": "3247559", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800001004000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf484d077ccd43519b5639acfe91b1a4e6981b5cc7f7e99f49bb14695cda8c160", - "transactionHash": "0x158efb24a1e0725ddea8fa9f2c637a63d25a9b86db2c75dd83ff4da979a3192e", + "contractAddress": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", + "transactionIndex": 56, + "gasUsed": "3157648", + "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000000", + "blockHash": "0xa931bd30b0b1a98460ecf13105220e297bf19dc4836a14dba8bc6630e86a7c5b", + "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", "logs": [ { - "transactionIndex": 44, - "blockNumber": 10131695, - "transactionHash": "0x158efb24a1e0725ddea8fa9f2c637a63d25a9b86db2c75dd83ff4da979a3192e", - "address": "0xaac727b9451268d7779F699dbaF6c2eAE571C369", + "transactionIndex": 56, + "blockNumber": 10339206, + "transactionHash": "0x5ec5811311e84d85b255d9ce83e6603df0f5fa5a3c06a63647739ecd40d47873", + "address": "0xfc4AC75C46C914aF5892d6d3eFFcebD7917293F1", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], "data": "0x", - "logIndex": 1545, - "blockHash": "0xf484d077ccd43519b5639acfe91b1a4e6981b5cc7f7e99f49bb14695cda8c160" + "logIndex": 77, + "blockHash": "0xa931bd30b0b1a98460ecf13105220e297bf19dc4836a14dba8bc6630e86a7c5b" } ], - "blockNumber": 10131695, - "cumulativeGasUsed": "11809601", + "blockNumber": 10339206, + "cumulativeGasUsed": "9266049", "status": 1, "byzantium": true }, @@ -656,11 +633,11 @@ "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" ] ], - "numDeployments": 6, - "solcInputHash": "a268c4117fbf03c1acd17a54ea249795", - "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\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"status\",\"type\":\"uint16\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"internalType\":\"struct HttpErrorItem[]\",\"name\":\"errors\",\"type\":\"tuple[]\"}],\"name\":\"HttpError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"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 (, HttpErrorItem[] memory errors) = abi.decode(\\n result.returnData,\\n (bytes4, HttpErrorItem[])\\n );\\n revert HttpError(errors);\\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\":\"0xa5a28872264a6164671800e3e1a604bc01fc2f316392651e9805b6901354cdf5\",\"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": "0x60a06040523480156200001157600080fd5b5060405162003c3038038062003c308339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613771620004bf600039600081816101ea015261151701526137716000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612388565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125a8565b61035c565b60405161015a929190612686565b610197610192366004612731565b610392565b60405161015a92919061279a565b6101b86101b3366004612823565b61047f565b60405161015a949392919061288f565b6101d061056f565b005b6101976101e03660046128cb565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461292a565b6105ab565b6101d06102563660046129f0565b61064e565b610176610269366004612a2d565b61066d565b61028161027c366004612a8c565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612ace565b61078c565b60405161015a9190612ae7565b6101b86102d4366004612afa565b610838565b6101976102e7366004612823565b61092a565b6101766102fa366004612823565b61096e565b6101b861030d366004612a8c565b6109e0565b6101d0610320366004612b6e565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b8b565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bc5565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c20565b91509150600083602001518060200190518101906105319190612c72565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bc5565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bc5565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122b5565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b8b565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b88886000611310565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b8b565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115be9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bc5565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b8b565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c9d565b90925090506060610bf98a8c018c612d55565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123ee565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123ee565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bc5565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bc5565b60200260200101516020015186602001518281518110610d4257610d42612bc5565b6020026020010181905250610ea5565b848281518110610d6457610d64612bc5565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bc5565b602002602001019015159081151581525050838281518110610dad57610dad612bc5565b602002602001015186602001518281518110610dcb57610dcb612bc5565b6020026020010181905250610e97565b828181518110610ded57610ded612bc5565b602002602001015160000151848381518110610e0b57610e0b612bc5565b6020026020010151848381518110610e2557610e25612bc5565b602002602001015160200151604051602401610e42929190612ed9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bc5565b60200260200101819052505b610ea2826001612f1d565b91505b80610eaf81612f30565b915050610cd3565b50610ec18561167d565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f49565b9050600080610f1383611a88565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612686565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fd3565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c20565b915091506000828060200190518101906110349190612c72565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123ee565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261167d565b9450505050965096945050505050565b8051610b6057602081015163ca7a4e7560e01b906112aa9061303c565b6001600160e01b031916036112f157600081602001518060200190518101906112d39190613074565b9150508060405163ca7a4e7560e01b81526004016104ec919061318a565b8060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60008060008086868681811061132857611328612bc5565b919091013560f81c915050600081900361134c5750600092508291508390506115b5565b60006113588287612f1d565b611363906001612f1d565b905060008260421480156113a95750888861137f896001612f1d565b81811061138e5761138e612bc5565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113e7575088886113bd600185613202565b8181106113cc576113cc612bc5565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561145f57611457600060408b8b6114008c6002612f1d565b9061140c600189613202565b9261141993929190613215565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611cb19050565b509050611491565b888861146c896001612f1d565b61147892859290613215565b60405161148692919061323f565b604051809103902090505b60008060006114a18c8c87611310565b925092509250600082856040516020016114c5929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561155e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115829190612c72565b90506001600160a01b038116156115a657995097508996506115b595505050505050565b50929850919650909450505050505b93509350939050565b60008060006115cd8585611d82565b90925090508161163f57600185516115e59190613202565b84146116335760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61164985826115be565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff8111156116a2576116a26123ee565b60405190808252806020026020018201604052801561170057816020015b6116ed604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116c05790505b50905060008367ffffffffffffffff81111561171e5761171e6123ee565b60405190808252806020026020018201604052801561176457816020015b60408051808201909152600081526060602082015281526020019060019003908161173c5790505b5090508367ffffffffffffffff811115611780576117806123ee565b6040519080825280602002602001820160405280156117c657816020015b60408051808201909152600081526060602082015281526020019060019003908161179e5790505b50945060006117d487611e39565b905060005b858110156119c7576000886020015182815181106117f9576117f9612bc5565b6020026020010151905060008960e00151838151811061181b5761181b612bc5565b6020026020010151905080156118675760405180604001604052806000151581526020018381525089848151811061185557611855612bc5565b602002602001018190525050506119b5565b600061187d8b60000151848d60a0015188611ed0565b809450819250505060008060008061189a8f60a001518887611f58565b9350935093509350831561191057828060200190518101906118bc91906132cf565b8b8d815181106118ce576118ce612bc5565b6020026020010181905250818a89815181106118ec576118ec612bc5565b602090810291909101015261190260018d612f1d565b9b50505050505050506119b5565b80801561191e575088602001515b1561193a57828060200190518101906119379190612f49565b92505b60405180604001604052808215158152602001848152508e898151811061196357611963612bc5565b60200260200101819052508e60200151888151811061198457611984612bc5565b60200260200101518a898151811061199e5761199e612bc5565b602002602001015160200181905250505050505050505b806119bf81612f30565b9150506117d9565b50836000036119da575050505050919050565b83835230876040015163a780bab660e01b856040516024016119fc91906133ca565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a5d95949392919061342c565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016134e9565b805160609060009081908490611a9f816002612f1d565b67ffffffffffffffff811115611ab757611ab76123ee565b6040519080825280601f01601f191660200182016040528015611ae1576020820181803683370190505b50945060009350808403611b2657600060f81b85600081518110611b0757611b07612bc5565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b3e57611b3e612bc5565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611c00578360f81b868260010181518110611ba457611ba4612bc5565b60200101906001600160f81b031916908160001a90535084611bcd846001840160ff8816612110565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c50565b600184019350828181518110611c1857611c18612bc5565b602001015160f81c60f81b868260010181518110611c3857611c38612bc5565b60200101906001600160f81b031916908160001a9053505b8015611c5f5760001901611b2c565b5083611c7083600060ff8716612110565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611b0757611b07612bc5565b8251600090600190831115611cc557600080fd5b611d16565b6000603a8210602f83111615611ce25750602f190190565b60478210604083111615611cf857506036190190565b60678210606083111615611d0e57506056190190565b5060ff919050565b60208501845b84811015611d7857611d338183015160001a611cca565b611d456001830184015160001a611cca565b60ff811460ff83141715611d5e57600094505050611d78565b60049190911b1760089490941b9390931792600201611d1c565b5050935093915050565b60008083518310611dd55760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611de957611de9612bc5565b016020015160f81c90508015611e1557611e0e85611e08866001612f1d565b83612110565b9250611e1a565b600092505b611e248185612f1d565b611e2f906001612f1d565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e6c90639061b92360e01b612134565b905083608001518015611e7d575080155b15611eb4576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f4c57826020015115611f305760018686604051602401611efc929190612ed9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f4284611f3d8761303c565b612134565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f8b57611f8487876121b9565b9050611f9b565b611f98878761c3506121cd565b90505b3d8115611fbf576000611faf600083612260565b9095509350600191506109219050565b60048110612106576000611fd560006004612260565b90506000611fed6004611fe88186613202565b612260565b9050630556f18360e41b6120008361303c565b6001600160e01b031916036120ce5760008060008060008580602001905181019061202b919061351d565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120c4576040518060600160405280866001600160a01b031681526020018581526020018481525060405160200161208291906135cd565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612103565b81816040516020016120e19291906135e0565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061211f8385612f1d565b111561212a57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121a6575060408051601f3d908101601f191682019092526121a39181019061360f565b60015b6121b257506000610356565b9050610356565b60006121c683835a6121cd565b9392505050565b60006001600160a01b0384163b61224c5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561227b5761227b6123ee565b6040519080825280601f01601f1916602001820160405280156122a5576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122fb579160200282015b828111156122fb57825182906122eb908261367b565b50916020019190600101906122d5565b5061230792915061230b565b5090565b8082111561230757600061231f8282612328565b5060010161230b565b50805461233490612b8b565b6000825580601f10612344575050565b601f016020900490600052602060002090810190610b6091905b80821115612307576000815560010161235e565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561239a57600080fd5b81356121c681612372565b60008083601f8401126123b757600080fd5b50813567ffffffffffffffff8111156123cf57600080fd5b6020830191508360208285010111156123e757600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612427576124276123ee565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612456576124566123ee565b604052919050565b600067ffffffffffffffff821115612478576124786123ee565b50601f01601f191660200190565b60006124996124948461245e565b61242d565b90508281528383830111156124ad57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124d557600080fd5b6121c683833560208501612486565b600067ffffffffffffffff8211156124fe576124fe6123ee565b5060051b60200190565b600082601f83011261251957600080fd5b81356020612529612494836124e4565b82815260059290921b8401810191818101908684111561254857600080fd5b8286015b8481101561259d57803567ffffffffffffffff81111561256c5760008081fd5b8701603f8101891361257e5760008081fd5b61258f898683013560408401612486565b84525091830191830161254c565b509695505050505050565b600080600080606085870312156125be57600080fd5b843567ffffffffffffffff808211156125d657600080fd5b6125e2888389016123a5565b909650945060208701359150808211156125fb57600080fd5b612607888389016124c4565b9350604087013591508082111561261d57600080fd5b5061262a87828801612508565b91505092959194509250565b60005b83811015612651578181015183820152602001612639565b50506000910152565b60008151808452612672816020860160208601612636565b601f01601f19169290920160200192915050565b604081526000612699604083018561265a565b90506001600160a01b03831660208301529392505050565b600082601f8301126126c257600080fd5b813560206126d2612494836124e4565b82815260059290921b840181019181810190868411156126f157600080fd5b8286015b8481101561259d57803567ffffffffffffffff8111156127155760008081fd5b6127238986838b01016124c4565b8452509183019183016126f5565b60008060006040848603121561274657600080fd5b833567ffffffffffffffff8082111561275e57600080fd5b61276a878388016123a5565b9095509350602086013591508082111561278357600080fd5b50612790868287016126b1565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561280457888603605f1901855281518051151587528301518387018890526127f18888018261265a565b96505093820193908201906001016127c3565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561283957600080fd5b843567ffffffffffffffff8082111561285157600080fd5b61285d888389016123a5565b9096509450602087013591508082111561287657600080fd5b50612883878288016123a5565b95989497509550505050565b6080815260006128a2608083018761265a565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128e157600080fd5b843567ffffffffffffffff808211156128f957600080fd5b612905888389016123a5565b9096509450602087013591508082111561291e57600080fd5b612607888389016126b1565b60008060008060008060a0878903121561294357600080fd5b863567ffffffffffffffff8082111561295b57600080fd5b6129678a838b016123a5565b9098509650602089013591508082111561298057600080fd5b61298c8a838b016124c4565b955060408901359150808211156129a257600080fd5b6129ae8a838b01612508565b9450606089013591506129c082612372565b909250608088013590808211156129d657600080fd5b506129e389828a016124c4565b9150509295509295509295565b600060208284031215612a0257600080fd5b813567ffffffffffffffff811115612a1957600080fd5b612a2584828501612508565b949350505050565b600080600060408486031215612a4257600080fd5b833567ffffffffffffffff80821115612a5a57600080fd5b612a66878388016123a5565b90955093506020860135915080821115612a7f57600080fd5b50612790868287016124c4565b60008060208385031215612a9f57600080fd5b823567ffffffffffffffff811115612ab657600080fd5b612ac2858286016123a5565b90969095509350505050565b600060208284031215612ae057600080fd5b5035919050565b6020815260006121c6602083018461265a565b600080600060408486031215612b0f57600080fd5b833567ffffffffffffffff80821115612b2757600080fd5b612b33878388016123a5565b90955093506020860135915080821115612b4c57600080fd5b5061279086828701612508565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b8057600080fd5b81356121c681612b59565b600181811c90821680612b9f57607f821691505b602082108103612bbf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bec57600080fd5b8151612bfa6124948261245e565b818152846020838601011115612c0f57600080fd5b612a25826020830160208701612636565b60008060408385031215612c3357600080fd5b825167ffffffffffffffff811115612c4a57600080fd5b612c5685828601612bdb565b9250506020830151612c6781612b59565b809150509250929050565b600060208284031215612c8457600080fd5b81516121c681612b59565b8015158114610b6057600080fd5b60008060408385031215612cb057600080fd5b823567ffffffffffffffff80821115612cc857600080fd5b818501915085601f830112612cdc57600080fd5b81356020612cec612494836124e4565b82815260059290921b84018101918181019089841115612d0b57600080fd5b948201945b83861015612d32578535612d2381612c8f565b82529482019490820190612d10565b96505086013592505080821115612d4857600080fd5b50611e2f858286016126b1565b600080600080600060a08688031215612d6d57600080fd5b612d778635612c8f565b85359450612d886020870135612b59565b6020860135935067ffffffffffffffff8060408801351115612da957600080fd5b612db98860408901358901612508565b93508060608801351115612dcc57600080fd5b612ddc88606089013589016124c4565b92508060808801351115612def57600080fd5b6080870135870188601f820112612e0557600080fd5b612e1261249482356124e4565b81358082526020808301929160051b8401018b1015612e3057600080fd5b602083015b6020843560051b850101811015612ec7578481351115612e5457600080fd5b803584016040818e03601f19011215612e6c57600080fd5b612e74612404565b612e816020830135612372565b602082013581528660408301351115612e9957600080fd5b612eac8e602060408501358501016124c4565b60208201528085525050602083019250602081019050612e35565b50809450505050509295509295909350565b604081526000612eec604083018561265a565b8281036020840152612efe818561265a565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f07565b600060018201612f4257612f42612f07565b5060010190565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612a2584828501612bdb565b600081518084526020808501808196508360051b8101915082860160005b85811015612fc6578284038952612fb484835161265a565b98850198935090840190600101612f9c565b5091979650505050505050565b60a081526000612fe660a083018861265a565b8281036020840152612ff8818861265a565b9050828103604084015261300c8187612f7e565b90506001600160e01b0319851660608401528281036080840152613030818561265a565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561306c5780818460040360031b1b83161693505b505050919050565b600080604080848603121561308857600080fd5b835161309381612372565b8093505060208085015167ffffffffffffffff808211156130b357600080fd5b818701915087601f8301126130c757600080fd5b81516130d5612494826124e4565b81815260059190911b8301840190848101908a8311156130f457600080fd5b8585015b83811015613178578051858111156131105760008081fd5b8601808d03601f19018913156131265760008081fd5b61312e612404565b8882015161ffff811681146131435760008081fd5b8152818a0151878111156131575760008081fd5b6131658f8b83860101612bdb565b828b0152508452509186019186016130f8565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156131f457888303603f190185528151805161ffff1684528701518784018790526131e18785018261265a565b95880195935050908601906001016131b1565b509098975050505050505050565b8181038181111561035657610356612f07565b6000808585111561322557600080fd5b8386111561323257600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261326057600080fd5b81516020613270612494836124e4565b82815260059290921b8401810191818101908684111561328f57600080fd5b8286015b8481101561259d57805167ffffffffffffffff8111156132b35760008081fd5b6132c18986838b0101612bdb565b845250918301918301613293565b6000602082840312156132e157600080fd5b815167ffffffffffffffff808211156132f957600080fd5b908301906060828603121561330d57600080fd5b604051606081018181108382111715613328576133286123ee565b604052825161333681612b59565b815260208301518281111561334a57600080fd5b6133568782860161324f565b60208301525060408301518281111561336e57600080fd5b61337a87828601612bdb565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526133b16060850182612f7e565b905060408301518482036040860152612efe828261265a565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561341f57603f1988860301845261340d858351613389565b945092850192908501906001016133f1565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261345860a0850188612f7e565b848103606086015261346a818861265a565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156134d657858303601f19018552815180516001600160e01b03191684528801518884018890526134c38885018261265a565b958901959350509087019060010161348d565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061350b60a0830187612f7e565b828103604084015261300c818761265a565b600080600080600060a0868803121561353557600080fd5b855161354081612b59565b602087015190955067ffffffffffffffff8082111561355e57600080fd5b61356a89838a0161324f565b9550604088015191508082111561358057600080fd5b61358c89838a01612bdb565b94506060880151915061359e82612372565b6080880151919350808211156135b357600080fd5b506135c088828901612bdb565b9150509295509295909350565b6020815260006121c66020830184613389565b600083516135f2818460208801612636565b835190830190613606818360208801612636565b01949350505050565b60006020828403121561362157600080fd5b81516121c681612c8f565b601f82111561367657600081815260208120601f850160051c810160208610156136535750805b601f850160051c820191505b818110156136725782815560010161365f565b5050505b505050565b815167ffffffffffffffff811115613695576136956123ee565b6136a9816136a38454612b8b565b8461362c565b602080601f8311600181146136de57600084156136c65750858301515b600019600386901b1c1916600185901b178555613672565b600085815260208120601f198616915b8281101561370d578886015182559484019460019091019084016136ee565b508582101561372b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea264697066735822122035159d52a0e04cc6441dfed903a33c70a9ca44587807027ddef3eb9b76c1cb2264736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612388565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125a8565b61035c565b60405161015a929190612686565b610197610192366004612731565b610392565b60405161015a92919061279a565b6101b86101b3366004612823565b61047f565b60405161015a949392919061288f565b6101d061056f565b005b6101976101e03660046128cb565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461292a565b6105ab565b6101d06102563660046129f0565b61064e565b610176610269366004612a2d565b61066d565b61028161027c366004612a8c565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612ace565b61078c565b60405161015a9190612ae7565b6101b86102d4366004612afa565b610838565b6101976102e7366004612823565b61092a565b6101766102fa366004612823565b61096e565b6101b861030d366004612a8c565b6109e0565b6101d0610320366004612b6e565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b8b565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bc5565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c20565b91509150600083602001518060200190518101906105319190612c72565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bc5565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bc5565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122b5565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b8b565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b88886000611310565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b8b565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115be9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bc5565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b8b565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c9d565b90925090506060610bf98a8c018c612d55565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123ee565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123ee565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bc5565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bc5565b60200260200101516020015186602001518281518110610d4257610d42612bc5565b6020026020010181905250610ea5565b848281518110610d6457610d64612bc5565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bc5565b602002602001019015159081151581525050838281518110610dad57610dad612bc5565b602002602001015186602001518281518110610dcb57610dcb612bc5565b6020026020010181905250610e97565b828181518110610ded57610ded612bc5565b602002602001015160000151848381518110610e0b57610e0b612bc5565b6020026020010151848381518110610e2557610e25612bc5565b602002602001015160200151604051602401610e42929190612ed9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bc5565b60200260200101819052505b610ea2826001612f1d565b91505b80610eaf81612f30565b915050610cd3565b50610ec18561167d565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f49565b9050600080610f1383611a88565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612686565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fd3565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c20565b915091506000828060200190518101906110349190612c72565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123ee565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261167d565b9450505050965096945050505050565b8051610b6057602081015163ca7a4e7560e01b906112aa9061303c565b6001600160e01b031916036112f157600081602001518060200190518101906112d39190613074565b9150508060405163ca7a4e7560e01b81526004016104ec919061318a565b8060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60008060008086868681811061132857611328612bc5565b919091013560f81c915050600081900361134c5750600092508291508390506115b5565b60006113588287612f1d565b611363906001612f1d565b905060008260421480156113a95750888861137f896001612f1d565b81811061138e5761138e612bc5565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113e7575088886113bd600185613202565b8181106113cc576113cc612bc5565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561145f57611457600060408b8b6114008c6002612f1d565b9061140c600189613202565b9261141993929190613215565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611cb19050565b509050611491565b888861146c896001612f1d565b61147892859290613215565b60405161148692919061323f565b604051809103902090505b60008060006114a18c8c87611310565b925092509250600082856040516020016114c5929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561155e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115829190612c72565b90506001600160a01b038116156115a657995097508996506115b595505050505050565b50929850919650909450505050505b93509350939050565b60008060006115cd8585611d82565b90925090508161163f57600185516115e59190613202565b84146116335760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61164985826115be565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff8111156116a2576116a26123ee565b60405190808252806020026020018201604052801561170057816020015b6116ed604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116c05790505b50905060008367ffffffffffffffff81111561171e5761171e6123ee565b60405190808252806020026020018201604052801561176457816020015b60408051808201909152600081526060602082015281526020019060019003908161173c5790505b5090508367ffffffffffffffff811115611780576117806123ee565b6040519080825280602002602001820160405280156117c657816020015b60408051808201909152600081526060602082015281526020019060019003908161179e5790505b50945060006117d487611e39565b905060005b858110156119c7576000886020015182815181106117f9576117f9612bc5565b6020026020010151905060008960e00151838151811061181b5761181b612bc5565b6020026020010151905080156118675760405180604001604052806000151581526020018381525089848151811061185557611855612bc5565b602002602001018190525050506119b5565b600061187d8b60000151848d60a0015188611ed0565b809450819250505060008060008061189a8f60a001518887611f58565b9350935093509350831561191057828060200190518101906118bc91906132cf565b8b8d815181106118ce576118ce612bc5565b6020026020010181905250818a89815181106118ec576118ec612bc5565b602090810291909101015261190260018d612f1d565b9b50505050505050506119b5565b80801561191e575088602001515b1561193a57828060200190518101906119379190612f49565b92505b60405180604001604052808215158152602001848152508e898151811061196357611963612bc5565b60200260200101819052508e60200151888151811061198457611984612bc5565b60200260200101518a898151811061199e5761199e612bc5565b602002602001015160200181905250505050505050505b806119bf81612f30565b9150506117d9565b50836000036119da575050505050919050565b83835230876040015163a780bab660e01b856040516024016119fc91906133ca565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a5d95949392919061342c565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016134e9565b805160609060009081908490611a9f816002612f1d565b67ffffffffffffffff811115611ab757611ab76123ee565b6040519080825280601f01601f191660200182016040528015611ae1576020820181803683370190505b50945060009350808403611b2657600060f81b85600081518110611b0757611b07612bc5565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b3e57611b3e612bc5565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611c00578360f81b868260010181518110611ba457611ba4612bc5565b60200101906001600160f81b031916908160001a90535084611bcd846001840160ff8816612110565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c50565b600184019350828181518110611c1857611c18612bc5565b602001015160f81c60f81b868260010181518110611c3857611c38612bc5565b60200101906001600160f81b031916908160001a9053505b8015611c5f5760001901611b2c565b5083611c7083600060ff8716612110565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611b0757611b07612bc5565b8251600090600190831115611cc557600080fd5b611d16565b6000603a8210602f83111615611ce25750602f190190565b60478210604083111615611cf857506036190190565b60678210606083111615611d0e57506056190190565b5060ff919050565b60208501845b84811015611d7857611d338183015160001a611cca565b611d456001830184015160001a611cca565b60ff811460ff83141715611d5e57600094505050611d78565b60049190911b1760089490941b9390931792600201611d1c565b5050935093915050565b60008083518310611dd55760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611de957611de9612bc5565b016020015160f81c90508015611e1557611e0e85611e08866001612f1d565b83612110565b9250611e1a565b600092505b611e248185612f1d565b611e2f906001612f1d565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e6c90639061b92360e01b612134565b905083608001518015611e7d575080155b15611eb4576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f4c57826020015115611f305760018686604051602401611efc929190612ed9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f4284611f3d8761303c565b612134565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f8b57611f8487876121b9565b9050611f9b565b611f98878761c3506121cd565b90505b3d8115611fbf576000611faf600083612260565b9095509350600191506109219050565b60048110612106576000611fd560006004612260565b90506000611fed6004611fe88186613202565b612260565b9050630556f18360e41b6120008361303c565b6001600160e01b031916036120ce5760008060008060008580602001905181019061202b919061351d565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120c4576040518060600160405280866001600160a01b031681526020018581526020018481525060405160200161208291906135cd565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612103565b81816040516020016120e19291906135e0565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061211f8385612f1d565b111561212a57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121a6575060408051601f3d908101601f191682019092526121a39181019061360f565b60015b6121b257506000610356565b9050610356565b60006121c683835a6121cd565b9392505050565b60006001600160a01b0384163b61224c5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561227b5761227b6123ee565b6040519080825280601f01601f1916602001820160405280156122a5576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122fb579160200282015b828111156122fb57825182906122eb908261367b565b50916020019190600101906122d5565b5061230792915061230b565b5090565b8082111561230757600061231f8282612328565b5060010161230b565b50805461233490612b8b565b6000825580601f10612344575050565b601f016020900490600052602060002090810190610b6091905b80821115612307576000815560010161235e565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561239a57600080fd5b81356121c681612372565b60008083601f8401126123b757600080fd5b50813567ffffffffffffffff8111156123cf57600080fd5b6020830191508360208285010111156123e757600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612427576124276123ee565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612456576124566123ee565b604052919050565b600067ffffffffffffffff821115612478576124786123ee565b50601f01601f191660200190565b60006124996124948461245e565b61242d565b90508281528383830111156124ad57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124d557600080fd5b6121c683833560208501612486565b600067ffffffffffffffff8211156124fe576124fe6123ee565b5060051b60200190565b600082601f83011261251957600080fd5b81356020612529612494836124e4565b82815260059290921b8401810191818101908684111561254857600080fd5b8286015b8481101561259d57803567ffffffffffffffff81111561256c5760008081fd5b8701603f8101891361257e5760008081fd5b61258f898683013560408401612486565b84525091830191830161254c565b509695505050505050565b600080600080606085870312156125be57600080fd5b843567ffffffffffffffff808211156125d657600080fd5b6125e2888389016123a5565b909650945060208701359150808211156125fb57600080fd5b612607888389016124c4565b9350604087013591508082111561261d57600080fd5b5061262a87828801612508565b91505092959194509250565b60005b83811015612651578181015183820152602001612639565b50506000910152565b60008151808452612672816020860160208601612636565b601f01601f19169290920160200192915050565b604081526000612699604083018561265a565b90506001600160a01b03831660208301529392505050565b600082601f8301126126c257600080fd5b813560206126d2612494836124e4565b82815260059290921b840181019181810190868411156126f157600080fd5b8286015b8481101561259d57803567ffffffffffffffff8111156127155760008081fd5b6127238986838b01016124c4565b8452509183019183016126f5565b60008060006040848603121561274657600080fd5b833567ffffffffffffffff8082111561275e57600080fd5b61276a878388016123a5565b9095509350602086013591508082111561278357600080fd5b50612790868287016126b1565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561280457888603605f1901855281518051151587528301518387018890526127f18888018261265a565b96505093820193908201906001016127c3565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561283957600080fd5b843567ffffffffffffffff8082111561285157600080fd5b61285d888389016123a5565b9096509450602087013591508082111561287657600080fd5b50612883878288016123a5565b95989497509550505050565b6080815260006128a2608083018761265a565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128e157600080fd5b843567ffffffffffffffff808211156128f957600080fd5b612905888389016123a5565b9096509450602087013591508082111561291e57600080fd5b612607888389016126b1565b60008060008060008060a0878903121561294357600080fd5b863567ffffffffffffffff8082111561295b57600080fd5b6129678a838b016123a5565b9098509650602089013591508082111561298057600080fd5b61298c8a838b016124c4565b955060408901359150808211156129a257600080fd5b6129ae8a838b01612508565b9450606089013591506129c082612372565b909250608088013590808211156129d657600080fd5b506129e389828a016124c4565b9150509295509295509295565b600060208284031215612a0257600080fd5b813567ffffffffffffffff811115612a1957600080fd5b612a2584828501612508565b949350505050565b600080600060408486031215612a4257600080fd5b833567ffffffffffffffff80821115612a5a57600080fd5b612a66878388016123a5565b90955093506020860135915080821115612a7f57600080fd5b50612790868287016124c4565b60008060208385031215612a9f57600080fd5b823567ffffffffffffffff811115612ab657600080fd5b612ac2858286016123a5565b90969095509350505050565b600060208284031215612ae057600080fd5b5035919050565b6020815260006121c6602083018461265a565b600080600060408486031215612b0f57600080fd5b833567ffffffffffffffff80821115612b2757600080fd5b612b33878388016123a5565b90955093506020860135915080821115612b4c57600080fd5b5061279086828701612508565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b8057600080fd5b81356121c681612b59565b600181811c90821680612b9f57607f821691505b602082108103612bbf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bec57600080fd5b8151612bfa6124948261245e565b818152846020838601011115612c0f57600080fd5b612a25826020830160208701612636565b60008060408385031215612c3357600080fd5b825167ffffffffffffffff811115612c4a57600080fd5b612c5685828601612bdb565b9250506020830151612c6781612b59565b809150509250929050565b600060208284031215612c8457600080fd5b81516121c681612b59565b8015158114610b6057600080fd5b60008060408385031215612cb057600080fd5b823567ffffffffffffffff80821115612cc857600080fd5b818501915085601f830112612cdc57600080fd5b81356020612cec612494836124e4565b82815260059290921b84018101918181019089841115612d0b57600080fd5b948201945b83861015612d32578535612d2381612c8f565b82529482019490820190612d10565b96505086013592505080821115612d4857600080fd5b50611e2f858286016126b1565b600080600080600060a08688031215612d6d57600080fd5b612d778635612c8f565b85359450612d886020870135612b59565b6020860135935067ffffffffffffffff8060408801351115612da957600080fd5b612db98860408901358901612508565b93508060608801351115612dcc57600080fd5b612ddc88606089013589016124c4565b92508060808801351115612def57600080fd5b6080870135870188601f820112612e0557600080fd5b612e1261249482356124e4565b81358082526020808301929160051b8401018b1015612e3057600080fd5b602083015b6020843560051b850101811015612ec7578481351115612e5457600080fd5b803584016040818e03601f19011215612e6c57600080fd5b612e74612404565b612e816020830135612372565b602082013581528660408301351115612e9957600080fd5b612eac8e602060408501358501016124c4565b60208201528085525050602083019250602081019050612e35565b50809450505050509295509295909350565b604081526000612eec604083018561265a565b8281036020840152612efe818561265a565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f07565b600060018201612f4257612f42612f07565b5060010190565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612a2584828501612bdb565b600081518084526020808501808196508360051b8101915082860160005b85811015612fc6578284038952612fb484835161265a565b98850198935090840190600101612f9c565b5091979650505050505050565b60a081526000612fe660a083018861265a565b8281036020840152612ff8818861265a565b9050828103604084015261300c8187612f7e565b90506001600160e01b0319851660608401528281036080840152613030818561265a565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561306c5780818460040360031b1b83161693505b505050919050565b600080604080848603121561308857600080fd5b835161309381612372565b8093505060208085015167ffffffffffffffff808211156130b357600080fd5b818701915087601f8301126130c757600080fd5b81516130d5612494826124e4565b81815260059190911b8301840190848101908a8311156130f457600080fd5b8585015b83811015613178578051858111156131105760008081fd5b8601808d03601f19018913156131265760008081fd5b61312e612404565b8882015161ffff811681146131435760008081fd5b8152818a0151878111156131575760008081fd5b6131658f8b83860101612bdb565b828b0152508452509186019186016130f8565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156131f457888303603f190185528151805161ffff1684528701518784018790526131e18785018261265a565b95880195935050908601906001016131b1565b509098975050505050505050565b8181038181111561035657610356612f07565b6000808585111561322557600080fd5b8386111561323257600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261326057600080fd5b81516020613270612494836124e4565b82815260059290921b8401810191818101908684111561328f57600080fd5b8286015b8481101561259d57805167ffffffffffffffff8111156132b35760008081fd5b6132c18986838b0101612bdb565b845250918301918301613293565b6000602082840312156132e157600080fd5b815167ffffffffffffffff808211156132f957600080fd5b908301906060828603121561330d57600080fd5b604051606081018181108382111715613328576133286123ee565b604052825161333681612b59565b815260208301518281111561334a57600080fd5b6133568782860161324f565b60208301525060408301518281111561336e57600080fd5b61337a87828601612bdb565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526133b16060850182612f7e565b905060408301518482036040860152612efe828261265a565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561341f57603f1988860301845261340d858351613389565b945092850192908501906001016133f1565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261345860a0850188612f7e565b848103606086015261346a818861265a565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156134d657858303601f19018552815180516001600160e01b03191684528801518884018890526134c38885018261265a565b958901959350509087019060010161348d565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061350b60a0830187612f7e565b828103604084015261300c818761265a565b600080600080600060a0868803121561353557600080fd5b855161354081612b59565b602087015190955067ffffffffffffffff8082111561355e57600080fd5b61356a89838a0161324f565b9550604088015191508082111561358057600080fd5b61358c89838a01612bdb565b94506060880151915061359e82612372565b6080880151919350808211156135b357600080fd5b506135c088828901612bdb565b9150509295509295909350565b6020815260006121c66020830184613389565b600083516135f2818460208801612636565b835190830190613606818360208801612636565b01949350505050565b60006020828403121561362157600080fd5b81516121c681612c8f565b601f82111561367657600081815260208120601f850160051c810160208610156136535750805b601f850160051c820191505b818110156136725782815560010161365f565b5050505b505050565b815167ffffffffffffffff811115613695576136956123ee565b6136a9816136a38454612b8b565b8461362c565b602080601f8311600181146136de57600084156136c65750858301515b600019600386901b1c1916600185901b178555613672565b600085815260208120601f198616915b8281101561370d578886015182559484019460019091019084016136ee565b508582101561372b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea264697066735822122035159d52a0e04cc6441dfed903a33c70a9ca44587807027ddef3eb9b76c1cb2264736f6c63430008110033", + "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", "devdoc": { "kind": "dev", "methods": { diff --git a/deployments/goerli/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json b/deployments/goerli/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json new file mode 100644 index 00000000..068c6c5c --- /dev/null +++ b/deployments/goerli/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.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 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 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" + }, + "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 83588e0f..2167ac81 100644 --- a/deployments/sepolia/UniversalResolver.json +++ b/deployments/sepolia/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0x64da0719987c29e0CEC0113D605996c6a4D4aB0c", + "address": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", "abi": [ { "inputs": [ @@ -17,29 +17,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint16", - "name": "status", - "type": "uint16" - }, - { - "internalType": "string", - "name": "message", - "type": "string" - } - ], - "internalType": "struct HttpErrorItem[]", - "name": "errors", - "type": "tuple[]" - } - ], - "name": "HttpError", - "type": "error" - }, { "inputs": [ { @@ -619,34 +596,34 @@ "type": "function" } ], - "transactionHash": "0x64d3578f35d87a427a33767edf2f591fef3c1960bdc791b6fd7a424f7fc60d0c", + "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", "receipt": { "to": null, "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", - "contractAddress": "0x64da0719987c29e0CEC0113D605996c6a4D4aB0c", - "transactionIndex": 51, - "gasUsed": "3247559", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000008000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000080000000000000000000000000000000000000000000000000000", - "blockHash": "0xf9245e48ef73f1a23a5295d20ff1616449181d771e8b77c5e968f8c49e25f7a0", - "transactionHash": "0x64d3578f35d87a427a33767edf2f591fef3c1960bdc791b6fd7a424f7fc60d0c", + "contractAddress": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", + "transactionIndex": 107, + "gasUsed": "3157648", + "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000004000000000000000000000000000000000000", + "blockHash": "0x338a8b517341cac3213d0605f18628405926d8601e031419a3cb6163a39b19e7", + "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", "logs": [ { - "transactionIndex": 51, - "blockNumber": 4793796, - "transactionHash": "0x64d3578f35d87a427a33767edf2f591fef3c1960bdc791b6fd7a424f7fc60d0c", - "address": "0x64da0719987c29e0CEC0113D605996c6a4D4aB0c", + "transactionIndex": 107, + "blockNumber": 5043334, + "transactionHash": "0x1e043817a1523404170294e32cd6d327476b52a4e3a5ba7035ad579f3a80e385", + "address": "0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], "data": "0x", - "logIndex": 32, - "blockHash": "0xf9245e48ef73f1a23a5295d20ff1616449181d771e8b77c5e968f8c49e25f7a0" + "logIndex": 197, + "blockHash": "0x338a8b517341cac3213d0605f18628405926d8601e031419a3cb6163a39b19e7" } ], - "blockNumber": 4793796, - "cumulativeGasUsed": "13544648", + "blockNumber": 5043334, + "cumulativeGasUsed": "16762495", "status": 1, "byzantium": true }, @@ -656,11 +633,11 @@ "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" ] ], - "numDeployments": 3, - "solcInputHash": "a268c4117fbf03c1acd17a54ea249795", - "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\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"status\",\"type\":\"uint16\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"internalType\":\"struct HttpErrorItem[]\",\"name\":\"errors\",\"type\":\"tuple[]\"}],\"name\":\"HttpError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"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 (, HttpErrorItem[] memory errors) = abi.decode(\\n result.returnData,\\n (bytes4, HttpErrorItem[])\\n );\\n revert HttpError(errors);\\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\":\"0xa5a28872264a6164671800e3e1a604bc01fc2f316392651e9805b6901354cdf5\",\"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": "0x60a06040523480156200001157600080fd5b5060405162003c3038038062003c308339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b608051613771620004bf600039600081816101ea015261151701526137716000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612388565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125a8565b61035c565b60405161015a929190612686565b610197610192366004612731565b610392565b60405161015a92919061279a565b6101b86101b3366004612823565b61047f565b60405161015a949392919061288f565b6101d061056f565b005b6101976101e03660046128cb565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461292a565b6105ab565b6101d06102563660046129f0565b61064e565b610176610269366004612a2d565b61066d565b61028161027c366004612a8c565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612ace565b61078c565b60405161015a9190612ae7565b6101b86102d4366004612afa565b610838565b6101976102e7366004612823565b61092a565b6101766102fa366004612823565b61096e565b6101b861030d366004612a8c565b6109e0565b6101d0610320366004612b6e565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b8b565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bc5565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c20565b91509150600083602001518060200190518101906105319190612c72565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bc5565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bc5565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122b5565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b8b565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b88886000611310565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b8b565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115be9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bc5565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b8b565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c9d565b90925090506060610bf98a8c018c612d55565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123ee565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123ee565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bc5565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bc5565b60200260200101516020015186602001518281518110610d4257610d42612bc5565b6020026020010181905250610ea5565b848281518110610d6457610d64612bc5565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bc5565b602002602001019015159081151581525050838281518110610dad57610dad612bc5565b602002602001015186602001518281518110610dcb57610dcb612bc5565b6020026020010181905250610e97565b828181518110610ded57610ded612bc5565b602002602001015160000151848381518110610e0b57610e0b612bc5565b6020026020010151848381518110610e2557610e25612bc5565b602002602001015160200151604051602401610e42929190612ed9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bc5565b60200260200101819052505b610ea2826001612f1d565b91505b80610eaf81612f30565b915050610cd3565b50610ec18561167d565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f49565b9050600080610f1383611a88565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612686565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fd3565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c20565b915091506000828060200190518101906110349190612c72565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123ee565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261167d565b9450505050965096945050505050565b8051610b6057602081015163ca7a4e7560e01b906112aa9061303c565b6001600160e01b031916036112f157600081602001518060200190518101906112d39190613074565b9150508060405163ca7a4e7560e01b81526004016104ec919061318a565b8060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60008060008086868681811061132857611328612bc5565b919091013560f81c915050600081900361134c5750600092508291508390506115b5565b60006113588287612f1d565b611363906001612f1d565b905060008260421480156113a95750888861137f896001612f1d565b81811061138e5761138e612bc5565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113e7575088886113bd600185613202565b8181106113cc576113cc612bc5565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561145f57611457600060408b8b6114008c6002612f1d565b9061140c600189613202565b9261141993929190613215565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611cb19050565b509050611491565b888861146c896001612f1d565b61147892859290613215565b60405161148692919061323f565b604051809103902090505b60008060006114a18c8c87611310565b925092509250600082856040516020016114c5929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561155e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115829190612c72565b90506001600160a01b038116156115a657995097508996506115b595505050505050565b50929850919650909450505050505b93509350939050565b60008060006115cd8585611d82565b90925090508161163f57600185516115e59190613202565b84146116335760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61164985826115be565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff8111156116a2576116a26123ee565b60405190808252806020026020018201604052801561170057816020015b6116ed604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116c05790505b50905060008367ffffffffffffffff81111561171e5761171e6123ee565b60405190808252806020026020018201604052801561176457816020015b60408051808201909152600081526060602082015281526020019060019003908161173c5790505b5090508367ffffffffffffffff811115611780576117806123ee565b6040519080825280602002602001820160405280156117c657816020015b60408051808201909152600081526060602082015281526020019060019003908161179e5790505b50945060006117d487611e39565b905060005b858110156119c7576000886020015182815181106117f9576117f9612bc5565b6020026020010151905060008960e00151838151811061181b5761181b612bc5565b6020026020010151905080156118675760405180604001604052806000151581526020018381525089848151811061185557611855612bc5565b602002602001018190525050506119b5565b600061187d8b60000151848d60a0015188611ed0565b809450819250505060008060008061189a8f60a001518887611f58565b9350935093509350831561191057828060200190518101906118bc91906132cf565b8b8d815181106118ce576118ce612bc5565b6020026020010181905250818a89815181106118ec576118ec612bc5565b602090810291909101015261190260018d612f1d565b9b50505050505050506119b5565b80801561191e575088602001515b1561193a57828060200190518101906119379190612f49565b92505b60405180604001604052808215158152602001848152508e898151811061196357611963612bc5565b60200260200101819052508e60200151888151811061198457611984612bc5565b60200260200101518a898151811061199e5761199e612bc5565b602002602001015160200181905250505050505050505b806119bf81612f30565b9150506117d9565b50836000036119da575050505050919050565b83835230876040015163a780bab660e01b856040516024016119fc91906133ca565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a5d95949392919061342c565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016134e9565b805160609060009081908490611a9f816002612f1d565b67ffffffffffffffff811115611ab757611ab76123ee565b6040519080825280601f01601f191660200182016040528015611ae1576020820181803683370190505b50945060009350808403611b2657600060f81b85600081518110611b0757611b07612bc5565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b3e57611b3e612bc5565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611c00578360f81b868260010181518110611ba457611ba4612bc5565b60200101906001600160f81b031916908160001a90535084611bcd846001840160ff8816612110565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c50565b600184019350828181518110611c1857611c18612bc5565b602001015160f81c60f81b868260010181518110611c3857611c38612bc5565b60200101906001600160f81b031916908160001a9053505b8015611c5f5760001901611b2c565b5083611c7083600060ff8716612110565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611b0757611b07612bc5565b8251600090600190831115611cc557600080fd5b611d16565b6000603a8210602f83111615611ce25750602f190190565b60478210604083111615611cf857506036190190565b60678210606083111615611d0e57506056190190565b5060ff919050565b60208501845b84811015611d7857611d338183015160001a611cca565b611d456001830184015160001a611cca565b60ff811460ff83141715611d5e57600094505050611d78565b60049190911b1760089490941b9390931792600201611d1c565b5050935093915050565b60008083518310611dd55760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611de957611de9612bc5565b016020015160f81c90508015611e1557611e0e85611e08866001612f1d565b83612110565b9250611e1a565b600092505b611e248185612f1d565b611e2f906001612f1d565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e6c90639061b92360e01b612134565b905083608001518015611e7d575080155b15611eb4576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f4c57826020015115611f305760018686604051602401611efc929190612ed9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f4284611f3d8761303c565b612134565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f8b57611f8487876121b9565b9050611f9b565b611f98878761c3506121cd565b90505b3d8115611fbf576000611faf600083612260565b9095509350600191506109219050565b60048110612106576000611fd560006004612260565b90506000611fed6004611fe88186613202565b612260565b9050630556f18360e41b6120008361303c565b6001600160e01b031916036120ce5760008060008060008580602001905181019061202b919061351d565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120c4576040518060600160405280866001600160a01b031681526020018581526020018481525060405160200161208291906135cd565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612103565b81816040516020016120e19291906135e0565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061211f8385612f1d565b111561212a57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121a6575060408051601f3d908101601f191682019092526121a39181019061360f565b60015b6121b257506000610356565b9050610356565b60006121c683835a6121cd565b9392505050565b60006001600160a01b0384163b61224c5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561227b5761227b6123ee565b6040519080825280601f01601f1916602001820160405280156122a5576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122fb579160200282015b828111156122fb57825182906122eb908261367b565b50916020019190600101906122d5565b5061230792915061230b565b5090565b8082111561230757600061231f8282612328565b5060010161230b565b50805461233490612b8b565b6000825580601f10612344575050565b601f016020900490600052602060002090810190610b6091905b80821115612307576000815560010161235e565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561239a57600080fd5b81356121c681612372565b60008083601f8401126123b757600080fd5b50813567ffffffffffffffff8111156123cf57600080fd5b6020830191508360208285010111156123e757600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612427576124276123ee565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612456576124566123ee565b604052919050565b600067ffffffffffffffff821115612478576124786123ee565b50601f01601f191660200190565b60006124996124948461245e565b61242d565b90508281528383830111156124ad57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124d557600080fd5b6121c683833560208501612486565b600067ffffffffffffffff8211156124fe576124fe6123ee565b5060051b60200190565b600082601f83011261251957600080fd5b81356020612529612494836124e4565b82815260059290921b8401810191818101908684111561254857600080fd5b8286015b8481101561259d57803567ffffffffffffffff81111561256c5760008081fd5b8701603f8101891361257e5760008081fd5b61258f898683013560408401612486565b84525091830191830161254c565b509695505050505050565b600080600080606085870312156125be57600080fd5b843567ffffffffffffffff808211156125d657600080fd5b6125e2888389016123a5565b909650945060208701359150808211156125fb57600080fd5b612607888389016124c4565b9350604087013591508082111561261d57600080fd5b5061262a87828801612508565b91505092959194509250565b60005b83811015612651578181015183820152602001612639565b50506000910152565b60008151808452612672816020860160208601612636565b601f01601f19169290920160200192915050565b604081526000612699604083018561265a565b90506001600160a01b03831660208301529392505050565b600082601f8301126126c257600080fd5b813560206126d2612494836124e4565b82815260059290921b840181019181810190868411156126f157600080fd5b8286015b8481101561259d57803567ffffffffffffffff8111156127155760008081fd5b6127238986838b01016124c4565b8452509183019183016126f5565b60008060006040848603121561274657600080fd5b833567ffffffffffffffff8082111561275e57600080fd5b61276a878388016123a5565b9095509350602086013591508082111561278357600080fd5b50612790868287016126b1565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561280457888603605f1901855281518051151587528301518387018890526127f18888018261265a565b96505093820193908201906001016127c3565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561283957600080fd5b843567ffffffffffffffff8082111561285157600080fd5b61285d888389016123a5565b9096509450602087013591508082111561287657600080fd5b50612883878288016123a5565b95989497509550505050565b6080815260006128a2608083018761265a565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128e157600080fd5b843567ffffffffffffffff808211156128f957600080fd5b612905888389016123a5565b9096509450602087013591508082111561291e57600080fd5b612607888389016126b1565b60008060008060008060a0878903121561294357600080fd5b863567ffffffffffffffff8082111561295b57600080fd5b6129678a838b016123a5565b9098509650602089013591508082111561298057600080fd5b61298c8a838b016124c4565b955060408901359150808211156129a257600080fd5b6129ae8a838b01612508565b9450606089013591506129c082612372565b909250608088013590808211156129d657600080fd5b506129e389828a016124c4565b9150509295509295509295565b600060208284031215612a0257600080fd5b813567ffffffffffffffff811115612a1957600080fd5b612a2584828501612508565b949350505050565b600080600060408486031215612a4257600080fd5b833567ffffffffffffffff80821115612a5a57600080fd5b612a66878388016123a5565b90955093506020860135915080821115612a7f57600080fd5b50612790868287016124c4565b60008060208385031215612a9f57600080fd5b823567ffffffffffffffff811115612ab657600080fd5b612ac2858286016123a5565b90969095509350505050565b600060208284031215612ae057600080fd5b5035919050565b6020815260006121c6602083018461265a565b600080600060408486031215612b0f57600080fd5b833567ffffffffffffffff80821115612b2757600080fd5b612b33878388016123a5565b90955093506020860135915080821115612b4c57600080fd5b5061279086828701612508565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b8057600080fd5b81356121c681612b59565b600181811c90821680612b9f57607f821691505b602082108103612bbf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bec57600080fd5b8151612bfa6124948261245e565b818152846020838601011115612c0f57600080fd5b612a25826020830160208701612636565b60008060408385031215612c3357600080fd5b825167ffffffffffffffff811115612c4a57600080fd5b612c5685828601612bdb565b9250506020830151612c6781612b59565b809150509250929050565b600060208284031215612c8457600080fd5b81516121c681612b59565b8015158114610b6057600080fd5b60008060408385031215612cb057600080fd5b823567ffffffffffffffff80821115612cc857600080fd5b818501915085601f830112612cdc57600080fd5b81356020612cec612494836124e4565b82815260059290921b84018101918181019089841115612d0b57600080fd5b948201945b83861015612d32578535612d2381612c8f565b82529482019490820190612d10565b96505086013592505080821115612d4857600080fd5b50611e2f858286016126b1565b600080600080600060a08688031215612d6d57600080fd5b612d778635612c8f565b85359450612d886020870135612b59565b6020860135935067ffffffffffffffff8060408801351115612da957600080fd5b612db98860408901358901612508565b93508060608801351115612dcc57600080fd5b612ddc88606089013589016124c4565b92508060808801351115612def57600080fd5b6080870135870188601f820112612e0557600080fd5b612e1261249482356124e4565b81358082526020808301929160051b8401018b1015612e3057600080fd5b602083015b6020843560051b850101811015612ec7578481351115612e5457600080fd5b803584016040818e03601f19011215612e6c57600080fd5b612e74612404565b612e816020830135612372565b602082013581528660408301351115612e9957600080fd5b612eac8e602060408501358501016124c4565b60208201528085525050602083019250602081019050612e35565b50809450505050509295509295909350565b604081526000612eec604083018561265a565b8281036020840152612efe818561265a565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f07565b600060018201612f4257612f42612f07565b5060010190565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612a2584828501612bdb565b600081518084526020808501808196508360051b8101915082860160005b85811015612fc6578284038952612fb484835161265a565b98850198935090840190600101612f9c565b5091979650505050505050565b60a081526000612fe660a083018861265a565b8281036020840152612ff8818861265a565b9050828103604084015261300c8187612f7e565b90506001600160e01b0319851660608401528281036080840152613030818561265a565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561306c5780818460040360031b1b83161693505b505050919050565b600080604080848603121561308857600080fd5b835161309381612372565b8093505060208085015167ffffffffffffffff808211156130b357600080fd5b818701915087601f8301126130c757600080fd5b81516130d5612494826124e4565b81815260059190911b8301840190848101908a8311156130f457600080fd5b8585015b83811015613178578051858111156131105760008081fd5b8601808d03601f19018913156131265760008081fd5b61312e612404565b8882015161ffff811681146131435760008081fd5b8152818a0151878111156131575760008081fd5b6131658f8b83860101612bdb565b828b0152508452509186019186016130f8565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156131f457888303603f190185528151805161ffff1684528701518784018790526131e18785018261265a565b95880195935050908601906001016131b1565b509098975050505050505050565b8181038181111561035657610356612f07565b6000808585111561322557600080fd5b8386111561323257600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261326057600080fd5b81516020613270612494836124e4565b82815260059290921b8401810191818101908684111561328f57600080fd5b8286015b8481101561259d57805167ffffffffffffffff8111156132b35760008081fd5b6132c18986838b0101612bdb565b845250918301918301613293565b6000602082840312156132e157600080fd5b815167ffffffffffffffff808211156132f957600080fd5b908301906060828603121561330d57600080fd5b604051606081018181108382111715613328576133286123ee565b604052825161333681612b59565b815260208301518281111561334a57600080fd5b6133568782860161324f565b60208301525060408301518281111561336e57600080fd5b61337a87828601612bdb565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526133b16060850182612f7e565b905060408301518482036040860152612efe828261265a565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561341f57603f1988860301845261340d858351613389565b945092850192908501906001016133f1565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261345860a0850188612f7e565b848103606086015261346a818861265a565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156134d657858303601f19018552815180516001600160e01b03191684528801518884018890526134c38885018261265a565b958901959350509087019060010161348d565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061350b60a0830187612f7e565b828103604084015261300c818761265a565b600080600080600060a0868803121561353557600080fd5b855161354081612b59565b602087015190955067ffffffffffffffff8082111561355e57600080fd5b61356a89838a0161324f565b9550604088015191508082111561358057600080fd5b61358c89838a01612bdb565b94506060880151915061359e82612372565b6080880151919350808211156135b357600080fd5b506135c088828901612bdb565b9150509295509295909350565b6020815260006121c66020830184613389565b600083516135f2818460208801612636565b835190830190613606818360208801612636565b01949350505050565b60006020828403121561362157600080fd5b81516121c681612c8f565b601f82111561367657600081815260208120601f850160051c810160208610156136535750805b601f850160051c820191505b818110156136725782815560010161365f565b5050505b505050565b815167ffffffffffffffff811115613695576136956123ee565b6136a9816136a38454612b8b565b8461362c565b602080601f8311600181146136de57600084156136c65750858301515b600019600386901b1c1916600185901b178555613672565b600085815260208120601f198616915b8281101561370d578886015182559484019460019091019084016136ee565b508582101561372b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea264697066735822122035159d52a0e04cc6441dfed903a33c70a9ca44587807027ddef3eb9b76c1cb2264736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102ec578063ec11c823146102ff578063f2fde38b1461031257600080fd5b8063b241d0d3146102c6578063b4a85801146102d957600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a657600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612388565b610325565b60405190151581526020015b60405180910390f35b6101766101713660046125a8565b61035c565b60405161015a929190612686565b610197610192366004612731565b610392565b60405161015a92919061279a565b6101b86101b3366004612823565b61047f565b60405161015a949392919061288f565b6101d061056f565b005b6101976101e03660046128cb565b610583565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461292a565b6105ab565b6101d06102563660046129f0565b61064e565b610176610269366004612a2d565b61066d565b61028161027c366004612a8c565b610766565b604080516001600160a01b03909416845260208401929092529082015260600161015a565b6102b96102b4366004612ace565b61078c565b60405161015a9190612ae7565b6101b86102d4366004612afa565b610838565b6101976102e7366004612823565b61092a565b6101766102fa366004612823565b61096e565b6101b861030d366004612a8c565b6109e0565b6101d0610320366004612b6e565b610ad3565b60006001600160e01b03198216639061b92360e01b148061035657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103848686868663e0a8541260e01b604051806020016040528060008152506105ab565b915091505b94509492505050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b8282101561046a5783829060005260206000200180546103dd90612b8b565b80601f016020809104026020016040519081016040528092919081815260200182805461040990612b8b565b80156104565780601f1061042b57610100808354040283529160200191610456565b820191906000526020600020905b81548152906001019060200180831161043957829003601f168201915b5050505050815260200190600101906103be565b50505050610583565b91509150935093915050565b6060600080808080808061049d8c8c8c8c636dc4fb7360e01b610b63565b93509350935093506000846000815181106104ba576104ba612bc5565b6020026020010151905080600001516104f5578060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60405180910390fd5b81511561054757600080838060200190518101906105139190612c20565b91509150600083602001518060200190518101906105319190612c72565b929b509199509750939550610564945050505050565b61055681602001518585610ee9565b985098509850985050505050505b945094509450949050565b61057761104a565b61058160006110a4565b565b606060006103848686868663b4a8580160e01b6040518060200160405280600081525061110c565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105c757905050905086816000815181106105f2576105f2612bc5565b602002602001018190525060008061060e8b8b858b8b8b61110c565b9150915060008260008151811061062757610627612bc5565b6020026020010151905061063a8161128d565b602001519b909a5098505050505050505050565b61065661104a565b80516106699060019060208401906122b5565b5050565b606060006104738585856001805480602002602001604051908101604052809291908181526020016000905b828210156107455783829060005260206000200180546106b890612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612b8b565b80156107315780601f1061070657610100808354040283529160200191610731565b820191906000526020600020905b81548152906001019060200180831161071457829003601f168201915b505050505081526020019060010190610699565b5050505063e0a8541260e01b604051806020016040528060008152506105ab565b60008060008060008061077b88886000611310565b919750955093505050509250925092565b6001818154811061079c57600080fd5b9060005260206000200160009150905080546107b790612b8b565b80601f01602080910402602001604051908101604052809291908181526020018280546107e390612b8b565b80156108305780601f1061080557610100808354040283529160200191610830565b820191906000526020600020905b81548152906001019060200180831161081357829003601f168201915b505050505081565b6060600080600080610884600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506115be9050565b60405160240161089691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f343100000000000000000000000000000000000000000000000000000000179052815190810190915260008082529192508190610906908b908b9086908c90636dc4fb7360e01b906105ab565b9150915061091582828a610ee9565b96509650965096505050505b93509350935093565b60606000808061095d888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b63565b50919a909950975050505050505050565b6060600080806109a1888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b63565b5050915091506000826000815181106109bc576109bc612bc5565b602002602001015190506109cf8161128d565b602001519890975095505050505050565b60606000806000610ac386866001805480602002602001604051908101604052809291908181526020016000905b82821015610aba578382906000526020600020018054610a2d90612b8b565b80601f0160208091040260200160405190810160405280929190818152602001828054610a5990612b8b565b8015610aa65780601f10610a7b57610100808354040283529160200191610aa6565b820191906000526020600020905b815481529060010190602001808311610a8957829003601f168201915b505050505081526020019060010190610a0e565b50505050610838565b9299919850965090945092505050565b610adb61104a565b6001600160a01b038116610b575760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016104ec565b610b60816110a4565b50565b60606000606080610bc760405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610be68b8d018d612c9d565b90925090506060610bf98a8c018c612d55565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610c3357600080fd5b805167ffffffffffffffff811115610c4d57610c4d6123ee565b604051908082528060200260200182016040528015610c8057816020015b6060815260200190600190039081610c6b5790505b506020850152805167ffffffffffffffff811115610ca057610ca06123ee565b604051908082528060200260200182016040528015610cc9578160200160208202803683370190505b5060e08501526000805b8251811015610eb7578251600090849083908110610cf357610cf3612bc5565b6020026020010151600001516001600160e01b03191603610d5257828181518110610d2057610d20612bc5565b60200260200101516020015186602001518281518110610d4257610d42612bc5565b6020026020010181905250610ea5565b848281518110610d6457610d64612bc5565b602002602001015115610ddb5760018660e001518281518110610d8957610d89612bc5565b602002602001019015159081151581525050838281518110610dad57610dad612bc5565b602002602001015186602001518281518110610dcb57610dcb612bc5565b6020026020010181905250610e97565b828181518110610ded57610ded612bc5565b602002602001015160000151848381518110610e0b57610e0b612bc5565b6020026020010151848381518110610e2557610e25612bc5565b602002602001015160200151604051602401610e42929190612ed9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e8b57610e8b612bc5565b60200260200101819052505b610ea2826001612f1d565b91505b80610eaf81612f30565b915050610cd3565b50610ec18561167d565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610f059190612f49565b9050600080610f1383611a88565b91509150600081604051602401610f2c91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f869187918e9101612686565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610fd5959493929190612fd3565b600060405180830381865afa158015610ff2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261101a9190810190612c20565b915091506000828060200190518101906110349190612c72565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104ec565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060600080600061111d8a8a610766565b919450849350909150506001600160a01b038216611167576040517f7199966d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0383163b6111a8576040517f4981ac0500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b81528315159261127d929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e09091019067ffffffffffffffff81111561124c5761124c6123ee565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905261167d565b9450505050965096945050505050565b8051610b6057602081015163ca7a4e7560e01b906112aa9061303c565b6001600160e01b031916036112f157600081602001518060200190518101906112d39190613074565b9150508060405163ca7a4e7560e01b81526004016104ec919061318a565b8060200151604051634ae063a960e11b81526004016104ec9190612ae7565b60008060008086868681811061132857611328612bc5565b919091013560f81c915050600081900361134c5750600092508291508390506115b5565b60006113588287612f1d565b611363906001612f1d565b905060008260421480156113a95750888861137f896001612f1d565b81811061138e5761138e612bc5565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156113e7575088886113bd600185613202565b8181106113cc576113cc612bc5565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b1561145f57611457600060408b8b6114008c6002612f1d565b9061140c600189613202565b9261141993929190613215565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611cb19050565b509050611491565b888861146c896001612f1d565b61147892859290613215565b60405161148692919061323f565b604051809103902090505b60008060006114a18c8c87611310565b925092509250600082856040516020016114c5929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561155e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115829190612c72565b90506001600160a01b038116156115a657995097508996506115b595505050505050565b50929850919650909450505050505b93509350939050565b60008060006115cd8585611d82565b90925090508161163f57600185516115e59190613202565b84146116335760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104ec565b50600091506103569050565b61164985826115be565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff8111156116a2576116a26123ee565b60405190808252806020026020018201604052801561170057816020015b6116ed604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816116c05790505b50905060008367ffffffffffffffff81111561171e5761171e6123ee565b60405190808252806020026020018201604052801561176457816020015b60408051808201909152600081526060602082015281526020019060019003908161173c5790505b5090508367ffffffffffffffff811115611780576117806123ee565b6040519080825280602002602001820160405280156117c657816020015b60408051808201909152600081526060602082015281526020019060019003908161179e5790505b50945060006117d487611e39565b905060005b858110156119c7576000886020015182815181106117f9576117f9612bc5565b6020026020010151905060008960e00151838151811061181b5761181b612bc5565b6020026020010151905080156118675760405180604001604052806000151581526020018381525089848151811061185557611855612bc5565b602002602001018190525050506119b5565b600061187d8b60000151848d60a0015188611ed0565b809450819250505060008060008061189a8f60a001518887611f58565b9350935093509350831561191057828060200190518101906118bc91906132cf565b8b8d815181106118ce576118ce612bc5565b6020026020010181905250818a89815181106118ec576118ec612bc5565b602090810291909101015261190260018d612f1d565b9b50505050505050506119b5565b80801561191e575088602001515b1561193a57828060200190518101906119379190612f49565b92505b60405180604001604052808215158152602001848152508e898151811061196357611963612bc5565b60200260200101819052508e60200151888151811061198457611984612bc5565b60200260200101518a898151811061199e5761199e612bc5565b602002602001015160200181905250505050505050505b806119bf81612f30565b9150506117d9565b50836000036119da575050505050919050565b83835230876040015163a780bab660e01b856040516024016119fc91906133ca565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c0015189604051602001611a5d95949392919061342c565b60408051601f1981840301815290829052630556f18360e41b82526104ec95949392916004016134e9565b805160609060009081908490611a9f816002612f1d565b67ffffffffffffffff811115611ab757611ab76123ee565b6040519080825280601f01601f191660200182016040528015611ae1576020820181803683370190505b50945060009350808403611b2657600060f81b85600081518110611b0757611b07612bc5565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611b3e57611b3e612bc5565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611c00578360f81b868260010181518110611ba457611ba4612bc5565b60200101906001600160f81b031916908160001a90535084611bcd846001840160ff8816612110565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611c50565b600184019350828181518110611c1857611c18612bc5565b602001015160f81c60f81b868260010181518110611c3857611c38612bc5565b60200101906001600160f81b031916908160001a9053505b8015611c5f5760001901611b2c565b5083611c7083600060ff8716612110565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611b0757611b07612bc5565b8251600090600190831115611cc557600080fd5b611d16565b6000603a8210602f83111615611ce25750602f190190565b60478210604083111615611cf857506036190190565b60678210606083111615611d0e57506056190190565b5060ff919050565b60208501845b84811015611d7857611d338183015160001a611cca565b611d456001830184015160001a611cca565b60ff811460ff83141715611d5e57600094505050611d78565b60049190911b1760089490941b9390931792600201611d1c565b5050935093915050565b60008083518310611dd55760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104ec565b6000848481518110611de957611de9612bc5565b016020015160f81c90508015611e1557611e0e85611e08866001612f1d565b83612110565b9250611e1a565b600092505b611e248185612f1d565b611e2f906001612f1d565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611e6c90639061b92360e01b612134565b905083608001518015611e7d575080155b15611eb4576040517f82c2c72800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611f4c57826020015115611f305760018686604051602401611efc929190612ed9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610389565b611f4284611f3d8761303c565b612134565b8591509150610389565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611f8b57611f8487876121b9565b9050611f9b565b611f98878761c3506121cd565b90505b3d8115611fbf576000611faf600083612260565b9095509350600191506109219050565b60048110612106576000611fd560006004612260565b90506000611fed6004611fe88186613202565b612260565b9050630556f18360e41b6120008361303c565b6001600160e01b031916036120ce5760008060008060008580602001905181019061202b919061351d565b945094509450945094508e6001600160a01b0316856001600160a01b0316036120c4576040518060600160405280866001600160a01b031681526020018581526020018481525060405160200161208291906135cd565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b5090995097506000965061092195505050505050565b5050505050612103565b81816040516020016120e19291906135e0565b60408051601f1981840301815291905260009750955086935061092192505050565b50505b5093509350935093565b825160009061211f8385612f1d565b111561212a57600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa935050505080156121a6575060408051601f3d908101601f191682019092526121a39181019061360f565b60015b6121b257506000610356565b9050610356565b60006121c683835a6121cd565b9392505050565b60006001600160a01b0384163b61224c5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e747261637400000000000000000000000000000000000060648201526084016104ec565b6000808451602086018786fa949350505050565b60608167ffffffffffffffff81111561227b5761227b6123ee565b6040519080825280601f01601f1916602001820160405280156122a5576020820181803683370190505b5090508183602083013e92915050565b8280548282559060005260206000209081019282156122fb579160200282015b828111156122fb57825182906122eb908261367b565b50916020019190600101906122d5565b5061230792915061230b565b5090565b8082111561230757600061231f8282612328565b5060010161230b565b50805461233490612b8b565b6000825580601f10612344575050565b601f016020900490600052602060002090810190610b6091905b80821115612307576000815560010161235e565b6001600160e01b031981168114610b6057600080fd5b60006020828403121561239a57600080fd5b81356121c681612372565b60008083601f8401126123b757600080fd5b50813567ffffffffffffffff8111156123cf57600080fd5b6020830191508360208285010111156123e757600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612427576124276123ee565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715612456576124566123ee565b604052919050565b600067ffffffffffffffff821115612478576124786123ee565b50601f01601f191660200190565b60006124996124948461245e565b61242d565b90508281528383830111156124ad57600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124d557600080fd5b6121c683833560208501612486565b600067ffffffffffffffff8211156124fe576124fe6123ee565b5060051b60200190565b600082601f83011261251957600080fd5b81356020612529612494836124e4565b82815260059290921b8401810191818101908684111561254857600080fd5b8286015b8481101561259d57803567ffffffffffffffff81111561256c5760008081fd5b8701603f8101891361257e5760008081fd5b61258f898683013560408401612486565b84525091830191830161254c565b509695505050505050565b600080600080606085870312156125be57600080fd5b843567ffffffffffffffff808211156125d657600080fd5b6125e2888389016123a5565b909650945060208701359150808211156125fb57600080fd5b612607888389016124c4565b9350604087013591508082111561261d57600080fd5b5061262a87828801612508565b91505092959194509250565b60005b83811015612651578181015183820152602001612639565b50506000910152565b60008151808452612672816020860160208601612636565b601f01601f19169290920160200192915050565b604081526000612699604083018561265a565b90506001600160a01b03831660208301529392505050565b600082601f8301126126c257600080fd5b813560206126d2612494836124e4565b82815260059290921b840181019181810190868411156126f157600080fd5b8286015b8481101561259d57803567ffffffffffffffff8111156127155760008081fd5b6127238986838b01016124c4565b8452509183019183016126f5565b60008060006040848603121561274657600080fd5b833567ffffffffffffffff8082111561275e57600080fd5b61276a878388016123a5565b9095509350602086013591508082111561278357600080fd5b50612790868287016126b1565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561280457888603605f1901855281518051151587528301518387018890526127f18888018261265a565b96505093820193908201906001016127c3565b50508395506001600160a01b0388168188015250505050509392505050565b6000806000806040858703121561283957600080fd5b843567ffffffffffffffff8082111561285157600080fd5b61285d888389016123a5565b9096509450602087013591508082111561287657600080fd5b50612883878288016123a5565b95989497509550505050565b6080815260006128a2608083018761265a565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156128e157600080fd5b843567ffffffffffffffff808211156128f957600080fd5b612905888389016123a5565b9096509450602087013591508082111561291e57600080fd5b612607888389016126b1565b60008060008060008060a0878903121561294357600080fd5b863567ffffffffffffffff8082111561295b57600080fd5b6129678a838b016123a5565b9098509650602089013591508082111561298057600080fd5b61298c8a838b016124c4565b955060408901359150808211156129a257600080fd5b6129ae8a838b01612508565b9450606089013591506129c082612372565b909250608088013590808211156129d657600080fd5b506129e389828a016124c4565b9150509295509295509295565b600060208284031215612a0257600080fd5b813567ffffffffffffffff811115612a1957600080fd5b612a2584828501612508565b949350505050565b600080600060408486031215612a4257600080fd5b833567ffffffffffffffff80821115612a5a57600080fd5b612a66878388016123a5565b90955093506020860135915080821115612a7f57600080fd5b50612790868287016124c4565b60008060208385031215612a9f57600080fd5b823567ffffffffffffffff811115612ab657600080fd5b612ac2858286016123a5565b90969095509350505050565b600060208284031215612ae057600080fd5b5035919050565b6020815260006121c6602083018461265a565b600080600060408486031215612b0f57600080fd5b833567ffffffffffffffff80821115612b2757600080fd5b612b33878388016123a5565b90955093506020860135915080821115612b4c57600080fd5b5061279086828701612508565b6001600160a01b0381168114610b6057600080fd5b600060208284031215612b8057600080fd5b81356121c681612b59565b600181811c90821680612b9f57607f821691505b602082108103612bbf57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612bec57600080fd5b8151612bfa6124948261245e565b818152846020838601011115612c0f57600080fd5b612a25826020830160208701612636565b60008060408385031215612c3357600080fd5b825167ffffffffffffffff811115612c4a57600080fd5b612c5685828601612bdb565b9250506020830151612c6781612b59565b809150509250929050565b600060208284031215612c8457600080fd5b81516121c681612b59565b8015158114610b6057600080fd5b60008060408385031215612cb057600080fd5b823567ffffffffffffffff80821115612cc857600080fd5b818501915085601f830112612cdc57600080fd5b81356020612cec612494836124e4565b82815260059290921b84018101918181019089841115612d0b57600080fd5b948201945b83861015612d32578535612d2381612c8f565b82529482019490820190612d10565b96505086013592505080821115612d4857600080fd5b50611e2f858286016126b1565b600080600080600060a08688031215612d6d57600080fd5b612d778635612c8f565b85359450612d886020870135612b59565b6020860135935067ffffffffffffffff8060408801351115612da957600080fd5b612db98860408901358901612508565b93508060608801351115612dcc57600080fd5b612ddc88606089013589016124c4565b92508060808801351115612def57600080fd5b6080870135870188601f820112612e0557600080fd5b612e1261249482356124e4565b81358082526020808301929160051b8401018b1015612e3057600080fd5b602083015b6020843560051b850101811015612ec7578481351115612e5457600080fd5b803584016040818e03601f19011215612e6c57600080fd5b612e74612404565b612e816020830135612372565b602082013581528660408301351115612e9957600080fd5b612eac8e602060408501358501016124c4565b60208201528085525050602083019250602081019050612e35565b50809450505050509295509295909350565b604081526000612eec604083018561265a565b8281036020840152612efe818561265a565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035657610356612f07565b600060018201612f4257612f42612f07565b5060010190565b600060208284031215612f5b57600080fd5b815167ffffffffffffffff811115612f7257600080fd5b612a2584828501612bdb565b600081518084526020808501808196508360051b8101915082860160005b85811015612fc6578284038952612fb484835161265a565b98850198935090840190600101612f9c565b5091979650505050505050565b60a081526000612fe660a083018861265a565b8281036020840152612ff8818861265a565b9050828103604084015261300c8187612f7e565b90506001600160e01b0319851660608401528281036080840152613030818561265a565b98975050505050505050565b6000815160208301516001600160e01b03198082169350600483101561306c5780818460040360031b1b83161693505b505050919050565b600080604080848603121561308857600080fd5b835161309381612372565b8093505060208085015167ffffffffffffffff808211156130b357600080fd5b818701915087601f8301126130c757600080fd5b81516130d5612494826124e4565b81815260059190911b8301840190848101908a8311156130f457600080fd5b8585015b83811015613178578051858111156131105760008081fd5b8601808d03601f19018913156131265760008081fd5b61312e612404565b8882015161ffff811681146131435760008081fd5b8152818a0151878111156131575760008081fd5b6131658f8b83860101612bdb565b828b0152508452509186019186016130f8565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b838110156131f457888303603f190185528151805161ffff1684528701518784018790526131e18785018261265a565b95880195935050908601906001016131b1565b509098975050505050505050565b8181038181111561035657610356612f07565b6000808585111561322557600080fd5b8386111561323257600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f83011261326057600080fd5b81516020613270612494836124e4565b82815260059290921b8401810191818101908684111561328f57600080fd5b8286015b8481101561259d57805167ffffffffffffffff8111156132b35760008081fd5b6132c18986838b0101612bdb565b845250918301918301613293565b6000602082840312156132e157600080fd5b815167ffffffffffffffff808211156132f957600080fd5b908301906060828603121561330d57600080fd5b604051606081018181108382111715613328576133286123ee565b604052825161333681612b59565b815260208301518281111561334a57600080fd5b6133568782860161324f565b60208301525060408301518281111561336e57600080fd5b61337a87828601612bdb565b60408301525095945050505050565b6001600160a01b03815116825260006020820151606060208501526133b16060850182612f7e565b905060408301518482036040860152612efe828261265a565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561341f57603f1988860301845261340d858351613389565b945092850192908501906001016133f1565b5092979650505050505050565b8515158152600060206001600160a01b03871681840152604060a08185015261345860a0850188612f7e565b848103606086015261346a818861265a565b905084810360808601528086518083528483019150848160051b84010185890160005b838110156134d657858303601f19018552815180516001600160e01b03191684528801518884018890526134c38885018261265a565b958901959350509087019060010161348d565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820152600061350b60a0830187612f7e565b828103604084015261300c818761265a565b600080600080600060a0868803121561353557600080fd5b855161354081612b59565b602087015190955067ffffffffffffffff8082111561355e57600080fd5b61356a89838a0161324f565b9550604088015191508082111561358057600080fd5b61358c89838a01612bdb565b94506060880151915061359e82612372565b6080880151919350808211156135b357600080fd5b506135c088828901612bdb565b9150509295509295909350565b6020815260006121c66020830184613389565b600083516135f2818460208801612636565b835190830190613606818360208801612636565b01949350505050565b60006020828403121561362157600080fd5b81516121c681612c8f565b601f82111561367657600081815260208120601f850160051c810160208610156136535750805b601f850160051c820191505b818110156136725782815560010161365f565b5050505b505050565b815167ffffffffffffffff811115613695576136956123ee565b6136a9816136a38454612b8b565b8461362c565b602080601f8311600181146136de57600084156136c65750858301515b600019600386901b1c1916600185901b178555613672565b600085815260208120601f198616915b8281101561370d578886015182559484019460019091019084016136ee565b508582101561372b5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea264697066735822122035159d52a0e04cc6441dfed903a33c70a9ca44587807027ddef3eb9b76c1cb2264736f6c63430008110033", + "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", "devdoc": { "kind": "dev", "methods": { diff --git a/deployments/sepolia/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json b/deployments/sepolia/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json new file mode 100644 index 00000000..068c6c5c --- /dev/null +++ b/deployments/sepolia/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.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 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 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" + }, + "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 From d3006c1e5399913295a31b69470dc68af24cb8b5 Mon Sep 17 00:00:00 2001 From: tate Date: Mon, 8 Jan 2024 12:04:59 +1100 Subject: [PATCH 4/4] mainnet --- deployments/mainnet/UniversalResolver.json | 77 +++++-------- .../b8a92c9207ae2a5ea22df4d7303f97f4.json | 101 ++++++++++++++++++ 2 files changed, 128 insertions(+), 50 deletions(-) create mode 100644 deployments/mainnet/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json diff --git a/deployments/mainnet/UniversalResolver.json b/deployments/mainnet/UniversalResolver.json index ecdeaf47..730e2f1d 100644 --- a/deployments/mainnet/UniversalResolver.json +++ b/deployments/mainnet/UniversalResolver.json @@ -1,5 +1,5 @@ { - "address": "0x20814C8e689187DfF7C93A9239ea22385d13b9F1", + "address": "0x8cab227b1162f03b8338331adaad7aadc83b895e", "abi": [ { "inputs": [ @@ -17,29 +17,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [ - { - "components": [ - { - "internalType": "uint16", - "name": "status", - "type": "uint16" - }, - { - "internalType": "string", - "name": "message", - "type": "string" - } - ], - "internalType": "struct HttpErrorItem[]", - "name": "errors", - "type": "tuple[]" - } - ], - "name": "HttpError", - "type": "error" - }, { "inputs": [ { @@ -619,36 +596,36 @@ "type": "function" } ], - "transactionHash": "0x085a2f7bb37f671302c629d12666a10290c36b15baa458da930e48f11157a353", + "transactionHash": "0x89fe62b8d107e87f8065de03c5bdd9f957e411776eff647011131737651d472d", "receipt": { "to": null, - "from": "0x69420f05A11f617B4B74fFe2E04B2D300dFA556F", - "contractAddress": "0x20814C8e689187DfF7C93A9239ea22385d13b9F1", - "transactionIndex": 29, - "gasUsed": "3169418", - "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000080000000000000800000000000000000000000000000000400000020000000000000040000000000000008000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x30343cec709808d48d4aede3da44186822757ad838bff211293cd51197fcbaab", - "transactionHash": "0x085a2f7bb37f671302c629d12666a10290c36b15baa458da930e48f11157a353", + "from": "0x69420f05a11f617b4b74ffe2e04b2d300dfa556f", + "contractAddress": "0x8cab227b1162f03b8338331adaad7aadc83b895e", + "transactionIndex": "0x4d", + "gasUsed": "0x302e90", + "logsBloom": "0x00000000010000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000004000000000000000000000000400000000000000000000040000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000002", + "blockHash": "0xbf913db8f7c8df11fdc99d2de36800dda5362d16253c8a3409312da54f65951c", + "transactionHash": "0xc8728c67dd0bc1ce47114e8d63a565bb92e45af2cc812bf2c8b9ee59e26f0b5d", "logs": [ { - "transactionIndex": 29, - "blockNumber": 18766888, - "transactionHash": "0x085a2f7bb37f671302c629d12666a10290c36b15baa458da930e48f11157a353", - "address": "0x20814C8e689187DfF7C93A9239ea22385d13b9F1", + "address": "0x8cab227b1162f03b8338331adaad7aadc83b895e", + "blockHash": "0xbf913db8f7c8df11fdc99d2de36800dda5362d16253c8a3409312da54f65951c", + "blockNumber": "0x1214a52", + "data": "0x", + "logIndex": "0x6f", + "removed": false, "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x00000000000000000000000069420f05a11f617b4b74ffe2e04b2d300dfa556f" ], - "data": "0x", - "logIndex": 122, - "blockHash": "0x30343cec709808d48d4aede3da44186822757ad838bff211293cd51197fcbaab" + "transactionHash": "0xc8728c67dd0bc1ce47114e8d63a565bb92e45af2cc812bf2c8b9ee59e26f0b5d", + "transactionIndex": "0x4d" } ], - "blockNumber": 18766888, - "cumulativeGasUsed": "8010597", - "status": 1, - "byzantium": true + "blockNumber": "0x1214a52", + "cumulativeGasUsed": "0x82275c", + "status": "0x1" }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", @@ -656,11 +633,11 @@ "https://universal-offchain-unwrapper-v2.ens-cf.workers.dev" ] ], - "numDeployments": 5, - "solcInputHash": "1f16f502a8b053fb7c640b7ed74a06d8", - "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\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"status\",\"type\":\"uint16\"},{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"internalType\":\"struct HttpErrorItem[]\",\"name\":\"errors\",\"type\":\"tuple[]\"}],\"name\":\"HttpError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"string[]\",\"name\":\"urls\",\"type\":\"string[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"bytes4\",\"name\":\"callbackFunction\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"OffchainLookup\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"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\":200},\"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 (, HttpErrorItem[] memory errors) = abi.decode(\\n result.returnData,\\n (bytes4, HttpErrorItem[])\\n );\\n revert HttpError(errors);\\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\":\"0xa5a28872264a6164671800e3e1a604bc01fc2f316392651e9805b6901354cdf5\",\"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": "0x60a06040523480156200001157600080fd5b5060405162003ab338038062003ab38339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6080516135f4620004bf600039600081816101ca015261141601526135f46000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80638e5ea8df116100a2578063b241d0d311610071578063b241d0d3146102a6578063b4a85801146102b9578063e0a85412146102cc578063ec11c823146102df578063f2fde38b146102f257600080fd5b80638e5ea8df146102285780639061b9231461023b578063a1cbcbaf1461024e578063a6b164191461028657600080fd5b8063715018a6116100e9578063715018a6146101a857806376286c00146101b25780637b103999146101c55780638da5cb5b146102045780638e25a0f31461021557600080fd5b806301ffc9a71461011b5780630667cfea14610143578063206c74c9146101645780636dc4fb7314610185575b600080fd5b61012e610129366004612226565b610305565b60405190151581526020015b60405180910390f35b610156610151366004612440565b61033c565b60405161013a92919061251d565b6101776101723660046125c6565b610372565b60405161013a92919061262e565b6101986101933660046126b7565b61045f565b60405161013a9493929190612722565b6101b061054f565b005b6101776101c036600461275e565b610563565b6101ec7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161013a565b6000546001600160a01b03166101ec565b6101566102233660046127bc565b61058b565b6101b0610236366004612881565b61062e565b6101566102493660046128bd565b61064d565b61026161025c36600461291b565b610746565b604080516001600160a01b03909416845260208401929092529082015260600161013a565b61029961029436600461295c565b61076c565b60405161013a9190612975565b6101986102b4366004612988565b610818565b6101776102c73660046126b7565b6108f1565b6101566102da3660046126b7565b61091c565b6101986102ed36600461291b565b610975565b6101b06103003660046129fb565b610a68565b60006001600160e01b03198216639061b92360e01b148061033657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103648686868663e0a8541260e01b6040518060200160405280600081525061058b565b915091505b94509492505050565b606060006104538585856001805480602002602001604051908101604052809291908181526020016000905b8282101561044a5783829060005260206000200180546103bd90612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546103e990612a18565b80156104365780601f1061040b57610100808354040283529160200191610436565b820191906000526020600020905b81548152906001019060200180831161041957829003601f168201915b50505050508152602001906001019061039e565b50505050610563565b91509150935093915050565b6060600080808080808061047d8c8c8c8c636dc4fb7360e01b610ae1565b935093509350935060008460008151811061049a5761049a612a52565b6020026020010151905080600001516104d5578060200151604051634ae063a960e11b81526004016104cc9190612975565b60405180910390fd5b81511561052757600080838060200190518101906104f39190612aad565b91509150600083602001518060200190518101906105119190612afe565b929b509199509750939550610544945050505050565b61053681602001518585610e65565b985098509850985050505050505b945094509450949050565b610557610fad565b6105616000611007565b565b606060006103648686868663b4a8580160e01b60405180602001604052806000815250611057565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105a757905050905086816000815181106105d2576105d2612a52565b60200260200101819052506000806105ee8b8b858b8b8b611057565b9150915060008260008151811061060757610607612a52565b6020026020010151905061061a816111a5565b602001519b909a5098505050505050505050565b610636610fad565b8051610649906001906020840190612153565b5050565b606060006104538585856001805480602002602001604051908101604052809291908181526020016000905b8282101561072557838290600052602060002001805461069890612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546106c490612a18565b80156107115780601f106106e657610100808354040283529160200191610711565b820191906000526020600020905b8154815290600101906020018083116106f457829003601f168201915b505050505081526020019060010190610679565b5050505063e0a8541260e01b6040518060200160405280600081525061058b565b60008060008060008061075b88886000611228565b919750955093505050509250925092565b6001818154811061077c57600080fd5b90600052602060002001600091509050805461079790612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546107c390612a18565b80156108105780601f106107e557610100808354040283529160200191610810565b820191906000526020600020905b8154815290600101906020018083116107f357829003601f168201915b505050505081565b6060600080600080610864600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506114bd9050565b60405160240161087691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b031663691f343160e01b1790528151908101909152600080825291925081906108cd908b908b9086908c90636dc4fb7360e01b9061058b565b915091506108dc82828a610e65565b96509650965096505050505b93509350935093565b60606000808061090b8888888863b4a8580160e01b610ae1565b50919a909950975050505050505050565b606060008080610936888888886370542a0960e11b610ae1565b50509150915060008260008151811061095157610951612a52565b60200260200101519050610964816111a5565b602001519890975095505050505050565b60606000806000610a5886866001805480602002602001604051908101604052809291908181526020016000905b82821015610a4f5783829060005260206000200180546109c290612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546109ee90612a18565b8015610a3b5780601f10610a1057610100808354040283529160200191610a3b565b820191906000526020600020905b815481529060010190602001808311610a1e57829003601f168201915b5050505050815260200190600101906109a3565b50505050610818565b9299919850965090945092505050565b610a70610fad565b6001600160a01b038116610ad55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104cc565b610ade81611007565b50565b60606000606080610b4560405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610b648b8d018d612b29565b90925090506060610b778a8c018c612be0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610bb157600080fd5b80516001600160401b03811115610bca57610bca61228b565b604051908082528060200260200182016040528015610bfd57816020015b6060815260200190600190039081610be85790505b50602085015280516001600160401b03811115610c1c57610c1c61228b565b604051908082528060200260200182016040528015610c45578160200160208202803683370190505b5060e08501526000805b8251811015610e33578251600090849083908110610c6f57610c6f612a52565b6020026020010151600001516001600160e01b03191603610cce57828181518110610c9c57610c9c612a52565b60200260200101516020015186602001518281518110610cbe57610cbe612a52565b6020026020010181905250610e21565b848281518110610ce057610ce0612a52565b602002602001015115610d575760018660e001518281518110610d0557610d05612a52565b602002602001019015159081151581525050838281518110610d2957610d29612a52565b602002602001015186602001518281518110610d4757610d47612a52565b6020026020010181905250610e13565b828181518110610d6957610d69612a52565b602002602001015160000151848381518110610d8757610d87612a52565b6020026020010151848381518110610da157610da1612a52565b602002602001015160200151604051602401610dbe929190612d63565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e0757610e07612a52565b60200260200101819052505b610e1e826001612da7565b91505b80610e2b81612dba565b915050610c4f565b50610e3d8561157c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610e819190612dd3565b9050600080610e8f83611984565b91509150600081604051602401610ea891815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316631d9dabef60e11b1790529051919250600091610ee99187918e910161251d565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610f38959493929190612e5c565b600060405180830381865afa158015610f55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f7d9190810190612aad565b91509150600082806020019051810190610f979190612afe565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104cc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006110688a8a610746565b919450849350909150506001600160a01b03821661109957604051637199966d60e01b815260040160405180910390fd5b6001600160a01b0383163b6110c157604051634981ac0560e01b815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b815283151592611195929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e0909101906001600160401b038111156111645761116461228b565b60405190808252806020026020018201604052801561118d578160200160208202803683370190505b50905261157c565b9450505050965096945050505050565b8051610ade57602081015163ca7a4e7560e01b906111c290612ec5565b6001600160e01b0319160361120957600081602001518060200190518101906111eb9190612efc565b9150508060405163ca7a4e7560e01b81526004016104cc9190613011565b8060200151604051634ae063a960e11b81526004016104cc9190612975565b60008060008086868681811061124057611240612a52565b919091013560f81c91505060008190036112645750600092508291508390506114b4565b60006112708287612da7565b61127b906001612da7565b905060008260421480156112c157508888611297896001612da7565b8181106112a6576112a6612a52565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156112ff575088886112d5600185613089565b8181106112e4576112e4612a52565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156113775761136f600060408b8b6113188c6002612da7565b90611324600189613089565b926113319392919061309c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611b789050565b5090506113a9565b8888611384896001612da7565b6113909285929061309c565b60405161139e9291906130c6565b604051809103902090505b60008060006113b98c8c87611228565b925092509250600082856040516020016113dd929190918252602082015260400190565b60408051601f19818403018152908290528051602090910120630178b8bf60e01b82526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561145d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114819190612afe565b90506001600160a01b038116156114a557995097508996506114b495505050505050565b50929850919650909450505050505b93509350939050565b60008060006114cc8585611c49565b90925090508161153e57600185516114e49190613089565b84146115325760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104cc565b50600091506103369050565b61154885826114bd565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b602081015151606090600080826001600160401b038111156115a0576115a061228b565b6040519080825280602002602001820160405280156115fe57816020015b6115eb604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816115be5790505b5090506000836001600160401b0381111561161b5761161b61228b565b60405190808252806020026020018201604052801561166157816020015b6040805180820190915260008152606060208201528152602001906001900390816116395790505b509050836001600160401b0381111561167c5761167c61228b565b6040519080825280602002602001820160405280156116c257816020015b60408051808201909152600081526060602082015281526020019060019003908161169a5790505b50945060006116d087611d00565b905060005b858110156118c3576000886020015182815181106116f5576116f5612a52565b6020026020010151905060008960e00151838151811061171757611717612a52565b6020026020010151905080156117635760405180604001604052806000151581526020018381525089848151811061175157611751612a52565b602002602001018190525050506118b1565b60006117798b60000151848d60a0015188611d7e565b80945081925050506000806000806117968f60a001518887611e06565b9350935093509350831561180c57828060200190518101906117b89190613155565b8b8d815181106117ca576117ca612a52565b6020026020010181905250818a89815181106117e8576117e8612a52565b60209081029190910101526117fe60018d612da7565b9b50505050505050506118b1565b80801561181a575088602001515b1561183657828060200190518101906118339190612dd3565b92505b60405180604001604052808215158152602001848152508e898151811061185f5761185f612a52565b60200260200101819052508e60200151888151811061188057611880612a52565b60200260200101518a898151811061189a5761189a612a52565b602002602001015160200181905250505050505050505b806118bb81612dba565b9150506116d5565b50836000036118d6575050505050919050565b83835230876040015163a780bab660e01b856040516024016118f8919061324e565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c00151896040516020016119599594939291906132b0565b60408051601f1981840301815290829052630556f18360e41b82526104cc959493929160040161336c565b80516060906000908190849061199b816002612da7565b6001600160401b038111156119b2576119b261228b565b6040519080825280601f01601f1916602001820160405280156119dc576020820181803683370190505b50945060009350808403611a2157600060f81b85600081518110611a0257611a02612a52565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611a3957611a39612a52565b01602001516001600160f81b031916601760f91b03611ac7578360f81b868260010181518110611a6b57611a6b612a52565b60200101906001600160f81b031916908160001a90535084611a94846001840160ff8816611fbe565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611b17565b600184019350828181518110611adf57611adf612a52565b602001015160f81c60f81b868260010181518110611aff57611aff612a52565b60200101906001600160f81b031916908160001a9053505b8015611b265760001901611a27565b5083611b3783600060ff8716611fbe565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611a0257611a02612a52565b8251600090600190831115611b8c57600080fd5b611bdd565b6000603a8210602f83111615611ba95750602f190190565b60478210604083111615611bbf57506036190190565b60678210606083111615611bd557506056190190565b5060ff919050565b60208501845b84811015611c3f57611bfa8183015160001a611b91565b611c0c6001830184015160001a611b91565b60ff811460ff83141715611c2557600094505050611c3f565b60049190911b1760089490941b9390931792600201611be3565b5050935093915050565b60008083518310611c9c5760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104cc565b6000848481518110611cb057611cb0612a52565b016020015160f81c90508015611cdc57611cd585611ccf866001612da7565b83611fbe565b9250611ce1565b600092505b611ceb8185612da7565b611cf6906001612da7565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611d3390639061b92360e01b611fe2565b905083608001518015611d44575080155b15611d625760405163105858e560e31b815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611dfa57826020015115611dde5760018686604051602401611daa929190612d63565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610369565b611df084611deb87612ec5565b611fe2565b8591509150610369565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611e3957611e328787612067565b9050611e49565b611e46878761c35061207b565b90505b3d8115611e6d576000611e5d6000836120ff565b9095509350600191506108e89050565b60048110611fb4576000611e83600060046120ff565b90506000611e9b6004611e968186613089565b6120ff565b9050630556f18360e41b611eae83612ec5565b6001600160e01b03191603611f7c57600080600080600085806020019051810190611ed991906133a2565b945094509450945094508e6001600160a01b0316856001600160a01b031603611f72576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611f309190613451565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108e895505050505050565b5050505050611fb1565b8181604051602001611f8f929190613464565b60408051601f198184030181529190526000975095508693506108e892505050565b50505b5093509350935093565b8251600090611fcd8385612da7565b1115611fd857600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612054575060408051601f3d908101601f1916820190925261205191810190613493565b60015b61206057506000610336565b9050610336565b600061207483835a61207b565b9392505050565b60006001600160a01b0384163b6120eb5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201526d1bc81b9bdb8b58dbdb9d1c9858dd60921b60648201526084016104cc565b6000808451602086018786fa949350505050565b6060816001600160401b038111156121195761211961228b565b6040519080825280601f01601f191660200182016040528015612143576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612199579160200282015b82811115612199578251829061218990826134ff565b5091602001919060010190612173565b506121a59291506121a9565b5090565b808211156121a55760006121bd82826121c6565b506001016121a9565b5080546121d290612a18565b6000825580601f106121e2575050565b601f016020900490600052602060002090810190610ade91905b808211156121a557600081556001016121fc565b6001600160e01b031981168114610ade57600080fd5b60006020828403121561223857600080fd5b813561207481612210565b60008083601f84011261225557600080fd5b5081356001600160401b0381111561226c57600080fd5b60208301915083602082850101111561228457600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156122c3576122c361228b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156122f1576122f161228b565b604052919050565b60006001600160401b038211156123125761231261228b565b50601f01601f191660200190565b600061233361232e846122f9565b6122c9565b905082815283838301111561234757600080fd5b828260208301376000602084830101529392505050565b600082601f83011261236f57600080fd5b61207483833560208501612320565b60006001600160401b038211156123975761239761228b565b5060051b60200190565b600082601f8301126123b257600080fd5b813560206123c261232e8361237e565b82815260059290921b840181019181810190868411156123e157600080fd5b8286015b848110156124355780356001600160401b038111156124045760008081fd5b8701603f810189136124165760008081fd5b612427898683013560408401612320565b8452509183019183016123e5565b509695505050505050565b6000806000806060858703121561245657600080fd5b84356001600160401b038082111561246d57600080fd5b61247988838901612243565b9096509450602087013591508082111561249257600080fd5b61249e8883890161235e565b935060408701359150808211156124b457600080fd5b506124c1878288016123a1565b91505092959194509250565b60005b838110156124e85781810151838201526020016124d0565b50506000910152565b600081518084526125098160208601602086016124cd565b601f01601f19169290920160200192915050565b60408152600061253060408301856124f1565b905060018060a01b03831660208301529392505050565b600082601f83011261255857600080fd5b8135602061256861232e8361237e565b82815260059290921b8401810191818101908684111561258757600080fd5b8286015b848110156124355780356001600160401b038111156125aa5760008081fd5b6125b88986838b010161235e565b84525091830191830161258b565b6000806000604084860312156125db57600080fd5b83356001600160401b03808211156125f257600080fd5b6125fe87838801612243565b9095509350602086013591508082111561261757600080fd5b5061262486828701612547565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561269857888603605f190185528151805115158752830151838701889052612685888801826124f1565b9650509382019390820190600101612657565b50506001600160a01b0397909716959096019490945295945050505050565b600080600080604085870312156126cd57600080fd5b84356001600160401b03808211156126e457600080fd5b6126f088838901612243565b9096509450602087013591508082111561270957600080fd5b5061271687828801612243565b95989497509550505050565b60808152600061273560808301876124f1565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561277457600080fd5b84356001600160401b038082111561278b57600080fd5b61279788838901612243565b909650945060208701359150808211156127b057600080fd5b61249e88838901612547565b60008060008060008060a087890312156127d557600080fd5b86356001600160401b03808211156127ec57600080fd5b6127f88a838b01612243565b9098509650602089013591508082111561281157600080fd5b61281d8a838b0161235e565b9550604089013591508082111561283357600080fd5b61283f8a838b016123a1565b94506060890135915061285182612210565b9092506080880135908082111561286757600080fd5b5061287489828a0161235e565b9150509295509295509295565b60006020828403121561289357600080fd5b81356001600160401b038111156128a957600080fd5b6128b5848285016123a1565b949350505050565b6000806000604084860312156128d257600080fd5b83356001600160401b03808211156128e957600080fd5b6128f587838801612243565b9095509350602086013591508082111561290e57600080fd5b506126248682870161235e565b6000806020838503121561292e57600080fd5b82356001600160401b0381111561294457600080fd5b61295085828601612243565b90969095509350505050565b60006020828403121561296e57600080fd5b5035919050565b60208152600061207460208301846124f1565b60008060006040848603121561299d57600080fd5b83356001600160401b03808211156129b457600080fd5b6129c087838801612243565b909550935060208601359150808211156129d957600080fd5b50612624868287016123a1565b6001600160a01b0381168114610ade57600080fd5b600060208284031215612a0d57600080fd5b8135612074816129e6565b600181811c90821680612a2c57607f821691505b602082108103612a4c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612a7957600080fd5b8151612a8761232e826122f9565b818152846020838601011115612a9c57600080fd5b6128b58260208301602087016124cd565b60008060408385031215612ac057600080fd5b82516001600160401b03811115612ad657600080fd5b612ae285828601612a68565b9250506020830151612af3816129e6565b809150509250929050565b600060208284031215612b1057600080fd5b8151612074816129e6565b8015158114610ade57600080fd5b60008060408385031215612b3c57600080fd5b82356001600160401b0380821115612b5357600080fd5b818501915085601f830112612b6757600080fd5b81356020612b7761232e8361237e565b82815260059290921b84018101918181019089841115612b9657600080fd5b948201945b83861015612bbd578535612bae81612b1b565b82529482019490820190612b9b565b96505086013592505080821115612bd357600080fd5b50611cf685828601612547565b600080600080600060a08688031215612bf857600080fd5b612c028635612b1b565b85359450612c1360208701356129e6565b602086013593506001600160401b038060408801351115612c3357600080fd5b612c4388604089013589016123a1565b93508060608801351115612c5657600080fd5b612c66886060890135890161235e565b92508060808801351115612c7957600080fd5b6080870135870188601f820112612c8f57600080fd5b612c9c61232e823561237e565b81358082526020808301929160051b8401018b1015612cba57600080fd5b602083015b6020843560051b850101811015612d51578481351115612cde57600080fd5b803584016040818e03601f19011215612cf657600080fd5b612cfe6122a1565b612d0b6020830135612210565b602082013581528660408301351115612d2357600080fd5b612d368e6020604085013585010161235e565b60208201528085525050602083019250602081019050612cbf565b50809450505050509295509295909350565b604081526000612d7660408301856124f1565b8281036020840152612d8881856124f1565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561033657610336612d91565b600060018201612dcc57612dcc612d91565b5060010190565b600060208284031215612de557600080fd5b81516001600160401b03811115612dfb57600080fd5b6128b584828501612a68565b600081518084526020808501808196508360051b8101915082860160005b85811015612e4f578284038952612e3d8483516124f1565b98850198935090840190600101612e25565b5091979650505050505050565b60a081526000612e6f60a08301886124f1565b8281036020840152612e8181886124f1565b90508281036040840152612e958187612e07565b6001600160e01b03198616606085015283810360808501529050612eb981856124f1565b98975050505050505050565b805160208201516001600160e01b03198082169291906004831015612ef45780818460040360031b1b83161693505b505050919050565b6000806040808486031215612f1057600080fd5b8351612f1b81612210565b809350506020808501516001600160401b0380821115612f3a57600080fd5b818701915087601f830112612f4e57600080fd5b8151612f5c61232e8261237e565b81815260059190911b8301840190848101908a831115612f7b57600080fd5b8585015b83811015612fff57805185811115612f975760008081fd5b8601808d03601f1901891315612fad5760008081fd5b612fb56122a1565b8882015161ffff81168114612fca5760008081fd5b8152818a015187811115612fde5760008081fd5b612fec8f8b83860101612a68565b828b015250845250918601918601612f7f565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561307b57888303603f190185528151805161ffff168452870151878401879052613068878501826124f1565b9588019593505090860190600101613038565b509098975050505050505050565b8181038181111561033657610336612d91565b600080858511156130ac57600080fd5b838611156130b957600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130e757600080fd5b815160206130f761232e8361237e565b82815260059290921b8401810191818101908684111561311657600080fd5b8286015b848110156124355780516001600160401b038111156131395760008081fd5b6131478986838b0101612a68565b84525091830191830161311a565b60006020828403121561316757600080fd5b81516001600160401b038082111561317e57600080fd5b908301906060828603121561319257600080fd5b6040516060810181811083821117156131ad576131ad61228b565b60405282516131bb816129e6565b81526020830151828111156131cf57600080fd5b6131db878286016130d6565b6020830152506040830151828111156131f357600080fd5b6131ff87828601612a68565b60408301525095945050505050565b60018060a01b03815116825260006020820151606060208501526132356060850182612e07565b905060408301518482036040860152612d8882826124f1565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132a357603f1988860301845261329185835161320e565b94509285019290850190600101613275565b5092979650505050505050565b85151581526000602060018060a01b03871681840152604060a0818501526132db60a0850188612e07565b84810360608601526132ed81886124f1565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561335957858303601f19018552815180516001600160e01b0319168452880151888401889052613346888501826124f1565b9589019593505090870190600101613310565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820181905260009061339090830187612e07565b8281036040840152612e9581876124f1565b600080600080600060a086880312156133ba57600080fd5b85516133c5816129e6565b60208701519095506001600160401b03808211156133e257600080fd5b6133ee89838a016130d6565b9550604088015191508082111561340457600080fd5b61341089838a01612a68565b94506060880151915061342282612210565b60808801519193508082111561343757600080fd5b5061344488828901612a68565b9150509295509295909350565b602081526000612074602083018461320e565b600083516134768184602088016124cd565b83519083019061348a8183602088016124cd565b01949350505050565b6000602082840312156134a557600080fd5b815161207481612b1b565b601f8211156134fa57600081815260208120601f850160051c810160208610156134d75750805b601f850160051c820191505b818110156134f6578281556001016134e3565b5050505b505050565b81516001600160401b038111156135185761351861228b565b61352c816135268454612a18565b846134b0565b602080601f83116001811461356157600084156135495750858301515b600019600386901b1c1916600185901b1785556134f6565b600085815260208120601f198616915b8281101561359057888601518255948401946001909101908401613571565b50858210156135ae5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212208634c5d4af4c93d564dd74cda8148bbcaaca136185b435687daeec24214a434164736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101165760003560e01c80638e5ea8df116100a2578063b241d0d311610071578063b241d0d3146102a6578063b4a85801146102b9578063e0a85412146102cc578063ec11c823146102df578063f2fde38b146102f257600080fd5b80638e5ea8df146102285780639061b9231461023b578063a1cbcbaf1461024e578063a6b164191461028657600080fd5b8063715018a6116100e9578063715018a6146101a857806376286c00146101b25780637b103999146101c55780638da5cb5b146102045780638e25a0f31461021557600080fd5b806301ffc9a71461011b5780630667cfea14610143578063206c74c9146101645780636dc4fb7314610185575b600080fd5b61012e610129366004612226565b610305565b60405190151581526020015b60405180910390f35b610156610151366004612440565b61033c565b60405161013a92919061251d565b6101776101723660046125c6565b610372565b60405161013a92919061262e565b6101986101933660046126b7565b61045f565b60405161013a9493929190612722565b6101b061054f565b005b6101776101c036600461275e565b610563565b6101ec7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161013a565b6000546001600160a01b03166101ec565b6101566102233660046127bc565b61058b565b6101b0610236366004612881565b61062e565b6101566102493660046128bd565b61064d565b61026161025c36600461291b565b610746565b604080516001600160a01b03909416845260208401929092529082015260600161013a565b61029961029436600461295c565b61076c565b60405161013a9190612975565b6101986102b4366004612988565b610818565b6101776102c73660046126b7565b6108f1565b6101566102da3660046126b7565b61091c565b6101986102ed36600461291b565b610975565b6101b06103003660046129fb565b610a68565b60006001600160e01b03198216639061b92360e01b148061033657506301ffc9a760e01b6001600160e01b03198316145b92915050565b606060006103648686868663e0a8541260e01b6040518060200160405280600081525061058b565b915091505b94509492505050565b606060006104538585856001805480602002602001604051908101604052809291908181526020016000905b8282101561044a5783829060005260206000200180546103bd90612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546103e990612a18565b80156104365780601f1061040b57610100808354040283529160200191610436565b820191906000526020600020905b81548152906001019060200180831161041957829003601f168201915b50505050508152602001906001019061039e565b50505050610563565b91509150935093915050565b6060600080808080808061047d8c8c8c8c636dc4fb7360e01b610ae1565b935093509350935060008460008151811061049a5761049a612a52565b6020026020010151905080600001516104d5578060200151604051634ae063a960e11b81526004016104cc9190612975565b60405180910390fd5b81511561052757600080838060200190518101906104f39190612aad565b91509150600083602001518060200190518101906105119190612afe565b929b509199509750939550610544945050505050565b61053681602001518585610e65565b985098509850985050505050505b945094509450949050565b610557610fad565b6105616000611007565b565b606060006103648686868663b4a8580160e01b60405180602001604052806000815250611057565b6040805160018082528183019092526060916000918291816020015b60608152602001906001900390816105a757905050905086816000815181106105d2576105d2612a52565b60200260200101819052506000806105ee8b8b858b8b8b611057565b9150915060008260008151811061060757610607612a52565b6020026020010151905061061a816111a5565b602001519b909a5098505050505050505050565b610636610fad565b8051610649906001906020840190612153565b5050565b606060006104538585856001805480602002602001604051908101604052809291908181526020016000905b8282101561072557838290600052602060002001805461069890612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546106c490612a18565b80156107115780601f106106e657610100808354040283529160200191610711565b820191906000526020600020905b8154815290600101906020018083116106f457829003601f168201915b505050505081526020019060010190610679565b5050505063e0a8541260e01b6040518060200160405280600081525061058b565b60008060008060008061075b88886000611228565b919750955093505050509250925092565b6001818154811061077c57600080fd5b90600052602060002001600091509050805461079790612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546107c390612a18565b80156108105780601f106107e557610100808354040283529160200191610810565b820191906000526020600020905b8154815290600101906020018083116107f357829003601f168201915b505050505081565b6060600080600080610864600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506114bd9050565b60405160240161087691815260200190565b60408051601f19818403018152918152602080830180516001600160e01b031663691f343160e01b1790528151908101909152600080825291925081906108cd908b908b9086908c90636dc4fb7360e01b9061058b565b915091506108dc82828a610e65565b96509650965096505050505b93509350935093565b60606000808061090b8888888863b4a8580160e01b610ae1565b50919a909950975050505050505050565b606060008080610936888888886370542a0960e11b610ae1565b50509150915060008260008151811061095157610951612a52565b60200260200101519050610964816111a5565b602001519890975095505050505050565b60606000806000610a5886866001805480602002602001604051908101604052809291908181526020016000905b82821015610a4f5783829060005260206000200180546109c290612a18565b80601f01602080910402602001604051908101604052809291908181526020018280546109ee90612a18565b8015610a3b5780601f10610a1057610100808354040283529160200191610a3b565b820191906000526020600020905b815481529060010190602001808311610a1e57829003601f168201915b5050505050815260200190600101906109a3565b50505050610818565b9299919850965090945092505050565b610a70610fad565b6001600160a01b038116610ad55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104cc565b610ade81611007565b50565b60606000606080610b4560405180610100016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160001515815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610b648b8d018d612b29565b90925090506060610b778a8c018c612be0565b60c089019190915260408801919091526001600160a01b0390911660a08701529015156080860152805183519192501015610bb157600080fd5b80516001600160401b03811115610bca57610bca61228b565b604051908082528060200260200182016040528015610bfd57816020015b6060815260200190600190039081610be85790505b50602085015280516001600160401b03811115610c1c57610c1c61228b565b604051908082528060200260200182016040528015610c45578160200160208202803683370190505b5060e08501526000805b8251811015610e33578251600090849083908110610c6f57610c6f612a52565b6020026020010151600001516001600160e01b03191603610cce57828181518110610c9c57610c9c612a52565b60200260200101516020015186602001518281518110610cbe57610cbe612a52565b6020026020010181905250610e21565b848281518110610ce057610ce0612a52565b602002602001015115610d575760018660e001518281518110610d0557610d05612a52565b602002602001019015159081151581525050838281518110610d2957610d29612a52565b602002602001015186602001518281518110610d4757610d47612a52565b6020026020010181905250610e13565b828181518110610d6957610d69612a52565b602002602001015160000151848381518110610d8757610d87612a52565b6020026020010151848381518110610da157610da1612a52565b602002602001015160200151604051602401610dbe929190612d63565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e0757610e07612a52565b60200260200101819052505b610e1e826001612da7565b91505b80610e2b81612dba565b915050610c4f565b50610e3d8561157c565b8560a0015186604001518760c001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610e819190612dd3565b9050600080610e8f83611984565b91509150600081604051602401610ea891815260200190565b60408051601f19818403018152918152602080830180516001600160e01b0316631d9dabef60e11b1790529051919250600091610ee99187918e910161251d565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610f38959493929190612e5c565b600060405180830381865afa158015610f55573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f7d9190810190612aad565b91509150600082806020019051810190610f979190612afe565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105615760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104cc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606060008060006110688a8a610746565b919450849350909150506001600160a01b03821661109957604051637199966d60e01b815260040160405180910390fd5b6001600160a01b0383163b6110c157604051634981ac0560e01b815260040160405180910390fd5b604080516101206020601f8d01819004028201810190925261010081018b815283151592611195929182918f908f9081908501838280828437600092019190915250505090825250602081018c9052604081018b90526001600160e01b03198a16606082015283151560808201526001600160a01b03871660a082015260c081018990528b5160e0909101906001600160401b038111156111645761116461228b565b60405190808252806020026020018201604052801561118d578160200160208202803683370190505b50905261157c565b9450505050965096945050505050565b8051610ade57602081015163ca7a4e7560e01b906111c290612ec5565b6001600160e01b0319160361120957600081602001518060200190518101906111eb9190612efc565b9150508060405163ca7a4e7560e01b81526004016104cc9190613011565b8060200151604051634ae063a960e11b81526004016104cc9190612975565b60008060008086868681811061124057611240612a52565b919091013560f81c91505060008190036112645750600092508291508390506114b4565b60006112708287612da7565b61127b906001612da7565b905060008260421480156112c157508888611297896001612da7565b8181106112a6576112a6612a52565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b80156112ff575088886112d5600185613089565b8181106112e4576112e4612a52565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b156113775761136f600060408b8b6113188c6002612da7565b90611324600189613089565b926113319392919061309c565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611b789050565b5090506113a9565b8888611384896001612da7565b6113909285929061309c565b60405161139e9291906130c6565b604051809103902090505b60008060006113b98c8c87611228565b925092509250600082856040516020016113dd929190918252602082015260400190565b60408051601f19818403018152908290528051602090910120630178b8bf60e01b82526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa15801561145d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114819190612afe565b90506001600160a01b038116156114a557995097508996506114b495505050505050565b50929850919650909450505050505b93509350939050565b60008060006114cc8585611c49565b90925090508161153e57600185516114e49190613089565b84146115325760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d6500000060448201526064016104cc565b50600091506103369050565b61154885826114bd565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b602081015151606090600080826001600160401b038111156115a0576115a061228b565b6040519080825280602002602001820160405280156115fe57816020015b6115eb604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816115be5790505b5090506000836001600160401b0381111561161b5761161b61228b565b60405190808252806020026020018201604052801561166157816020015b6040805180820190915260008152606060208201528152602001906001900390816116395790505b509050836001600160401b0381111561167c5761167c61228b565b6040519080825280602002602001820160405280156116c257816020015b60408051808201909152600081526060602082015281526020019060019003908161169a5790505b50945060006116d087611d00565b905060005b858110156118c3576000886020015182815181106116f5576116f5612a52565b6020026020010151905060008960e00151838151811061171757611717612a52565b6020026020010151905080156117635760405180604001604052806000151581526020018381525089848151811061175157611751612a52565b602002602001018190525050506118b1565b60006117798b60000151848d60a0015188611d7e565b80945081925050506000806000806117968f60a001518887611e06565b9350935093509350831561180c57828060200190518101906117b89190613155565b8b8d815181106117ca576117ca612a52565b6020026020010181905250818a89815181106117e8576117e8612a52565b60209081029190910101526117fe60018d612da7565b9b50505050505050506118b1565b80801561181a575088602001515b1561183657828060200190518101906118339190612dd3565b92505b60405180604001604052808215158152602001848152508e898151811061185f5761185f612a52565b60200260200101819052508e60200151888151811061188057611880612a52565b60200260200101518a898151811061189a5761189a612a52565b602002602001015160200181905250505050505050505b806118bb81612dba565b9150506116d5565b50836000036118d6575050505050919050565b83835230876040015163a780bab660e01b856040516024016118f8919061324e565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505089606001518a608001518b60a001518c604001518d60c00151896040516020016119599594939291906132b0565b60408051601f1981840301815290829052630556f18360e41b82526104cc959493929160040161336c565b80516060906000908190849061199b816002612da7565b6001600160401b038111156119b2576119b261228b565b6040519080825280601f01601f1916602001820160405280156119dc576020820181803683370190505b50945060009350808403611a2157600060f81b85600081518110611a0257611a02612a52565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b828181518110611a3957611a39612a52565b01602001516001600160f81b031916601760f91b03611ac7578360f81b868260010181518110611a6b57611a6b612a52565b60200101906001600160f81b031916908160001a90535084611a94846001840160ff8816611fbe565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611b17565b600184019350828181518110611adf57611adf612a52565b602001015160f81c60f81b868260010181518110611aff57611aff612a52565b60200101906001600160f81b031916908160001a9053505b8015611b265760001901611a27565b5083611b3783600060ff8716611fbe565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b85600081518110611a0257611a02612a52565b8251600090600190831115611b8c57600080fd5b611bdd565b6000603a8210602f83111615611ba95750602f190190565b60478210604083111615611bbf57506036190190565b60678210606083111615611bd557506056190190565b5060ff919050565b60208501845b84811015611c3f57611bfa8183015160001a611b91565b611c0c6001830184015160001a611b91565b60ff811460ff83141715611c2557600094505050611c3f565b60049190911b1760089490941b9390931792600201611be3565b5050935093915050565b60008083518310611c9c5760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e6473000060448201526064016104cc565b6000848481518110611cb057611cb0612a52565b016020015160f81c90508015611cdc57611cd585611ccf866001612da7565b83611fbe565b9250611ce1565b600092505b611ceb8185612da7565b611cf6906001612da7565b9150509250929050565b604080518082019091526000808252602082015281515160a0830151901590600090611d3390639061b92360e01b611fe2565b905083608001518015611d44575080155b15611d625760405163105858e560e31b815260040160405180910390fd5b6040805180820190915291151582521515602082015292915050565b600060608260000151611dfa57826020015115611dde5760018686604051602401611daa929190612d63565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b1790529092509050610369565b611df084611deb87612ec5565b611fe2565b8591509150610369565b50600195939450505050565b604080518082019091526000808252606060208301819052909160008415611e3957611e328787612067565b9050611e49565b611e46878761c35061207b565b90505b3d8115611e6d576000611e5d6000836120ff565b9095509350600191506108e89050565b60048110611fb4576000611e83600060046120ff565b90506000611e9b6004611e968186613089565b6120ff565b9050630556f18360e41b611eae83612ec5565b6001600160e01b03191603611f7c57600080600080600085806020019051810190611ed991906133a2565b945094509450945094508e6001600160a01b0316856001600160a01b031603611f72576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611f309190613451565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b509099509750600096506108e895505050505050565b5050505050611fb1565b8181604051602001611f8f929190613464565b60408051601f198184030181529190526000975095508693506108e892505050565b50505b5093509350935093565b8251600090611fcd8385612da7565b1115611fd857600080fd5b5091016020012090565b6040516301ffc9a760e01b81526001600160e01b0319821660048201526000906001600160a01b038416906301ffc9a79061c350906024016020604051808303818786fa93505050508015612054575060408051601f3d908101601f1916820190925261205191810190613493565b60015b61206057506000610336565b9050610336565b600061207483835a61207b565b9392505050565b60006001600160a01b0384163b6120eb5760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201526d1bc81b9bdb8b58dbdb9d1c9858dd60921b60648201526084016104cc565b6000808451602086018786fa949350505050565b6060816001600160401b038111156121195761211961228b565b6040519080825280601f01601f191660200182016040528015612143576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612199579160200282015b82811115612199578251829061218990826134ff565b5091602001919060010190612173565b506121a59291506121a9565b5090565b808211156121a55760006121bd82826121c6565b506001016121a9565b5080546121d290612a18565b6000825580601f106121e2575050565b601f016020900490600052602060002090810190610ade91905b808211156121a557600081556001016121fc565b6001600160e01b031981168114610ade57600080fd5b60006020828403121561223857600080fd5b813561207481612210565b60008083601f84011261225557600080fd5b5081356001600160401b0381111561226c57600080fd5b60208301915083602082850101111561228457600080fd5b9250929050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b03811182821017156122c3576122c361228b565b60405290565b604051601f8201601f191681016001600160401b03811182821017156122f1576122f161228b565b604052919050565b60006001600160401b038211156123125761231261228b565b50601f01601f191660200190565b600061233361232e846122f9565b6122c9565b905082815283838301111561234757600080fd5b828260208301376000602084830101529392505050565b600082601f83011261236f57600080fd5b61207483833560208501612320565b60006001600160401b038211156123975761239761228b565b5060051b60200190565b600082601f8301126123b257600080fd5b813560206123c261232e8361237e565b82815260059290921b840181019181810190868411156123e157600080fd5b8286015b848110156124355780356001600160401b038111156124045760008081fd5b8701603f810189136124165760008081fd5b612427898683013560408401612320565b8452509183019183016123e5565b509695505050505050565b6000806000806060858703121561245657600080fd5b84356001600160401b038082111561246d57600080fd5b61247988838901612243565b9096509450602087013591508082111561249257600080fd5b61249e8883890161235e565b935060408701359150808211156124b457600080fd5b506124c1878288016123a1565b91505092959194509250565b60005b838110156124e85781810151838201526020016124d0565b50506000910152565b600081518084526125098160208601602086016124cd565b601f01601f19169290920160200192915050565b60408152600061253060408301856124f1565b905060018060a01b03831660208301529392505050565b600082601f83011261255857600080fd5b8135602061256861232e8361237e565b82815260059290921b8401810191818101908684111561258757600080fd5b8286015b848110156124355780356001600160401b038111156125aa5760008081fd5b6125b88986838b010161235e565b84525091830191830161258b565b6000806000604084860312156125db57600080fd5b83356001600160401b03808211156125f257600080fd5b6125fe87838801612243565b9095509350602086013591508082111561261757600080fd5b5061262486828701612547565b9150509250925092565b6000604080830181845280865180835260608601915060608160051b8701019250602080890160005b8381101561269857888603605f190185528151805115158752830151838701889052612685888801826124f1565b9650509382019390820190600101612657565b50506001600160a01b0397909716959096019490945295945050505050565b600080600080604085870312156126cd57600080fd5b84356001600160401b03808211156126e457600080fd5b6126f088838901612243565b9096509450602087013591508082111561270957600080fd5b5061271687828801612243565b95989497509550505050565b60808152600061273560808301876124f1565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b6000806000806060858703121561277457600080fd5b84356001600160401b038082111561278b57600080fd5b61279788838901612243565b909650945060208701359150808211156127b057600080fd5b61249e88838901612547565b60008060008060008060a087890312156127d557600080fd5b86356001600160401b03808211156127ec57600080fd5b6127f88a838b01612243565b9098509650602089013591508082111561281157600080fd5b61281d8a838b0161235e565b9550604089013591508082111561283357600080fd5b61283f8a838b016123a1565b94506060890135915061285182612210565b9092506080880135908082111561286757600080fd5b5061287489828a0161235e565b9150509295509295509295565b60006020828403121561289357600080fd5b81356001600160401b038111156128a957600080fd5b6128b5848285016123a1565b949350505050565b6000806000604084860312156128d257600080fd5b83356001600160401b03808211156128e957600080fd5b6128f587838801612243565b9095509350602086013591508082111561290e57600080fd5b506126248682870161235e565b6000806020838503121561292e57600080fd5b82356001600160401b0381111561294457600080fd5b61295085828601612243565b90969095509350505050565b60006020828403121561296e57600080fd5b5035919050565b60208152600061207460208301846124f1565b60008060006040848603121561299d57600080fd5b83356001600160401b03808211156129b457600080fd5b6129c087838801612243565b909550935060208601359150808211156129d957600080fd5b50612624868287016123a1565b6001600160a01b0381168114610ade57600080fd5b600060208284031215612a0d57600080fd5b8135612074816129e6565b600181811c90821680612a2c57607f821691505b602082108103612a4c57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b600082601f830112612a7957600080fd5b8151612a8761232e826122f9565b818152846020838601011115612a9c57600080fd5b6128b58260208301602087016124cd565b60008060408385031215612ac057600080fd5b82516001600160401b03811115612ad657600080fd5b612ae285828601612a68565b9250506020830151612af3816129e6565b809150509250929050565b600060208284031215612b1057600080fd5b8151612074816129e6565b8015158114610ade57600080fd5b60008060408385031215612b3c57600080fd5b82356001600160401b0380821115612b5357600080fd5b818501915085601f830112612b6757600080fd5b81356020612b7761232e8361237e565b82815260059290921b84018101918181019089841115612b9657600080fd5b948201945b83861015612bbd578535612bae81612b1b565b82529482019490820190612b9b565b96505086013592505080821115612bd357600080fd5b50611cf685828601612547565b600080600080600060a08688031215612bf857600080fd5b612c028635612b1b565b85359450612c1360208701356129e6565b602086013593506001600160401b038060408801351115612c3357600080fd5b612c4388604089013589016123a1565b93508060608801351115612c5657600080fd5b612c66886060890135890161235e565b92508060808801351115612c7957600080fd5b6080870135870188601f820112612c8f57600080fd5b612c9c61232e823561237e565b81358082526020808301929160051b8401018b1015612cba57600080fd5b602083015b6020843560051b850101811015612d51578481351115612cde57600080fd5b803584016040818e03601f19011215612cf657600080fd5b612cfe6122a1565b612d0b6020830135612210565b602082013581528660408301351115612d2357600080fd5b612d368e6020604085013585010161235e565b60208201528085525050602083019250602081019050612cbf565b50809450505050509295509295909350565b604081526000612d7660408301856124f1565b8281036020840152612d8881856124f1565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561033657610336612d91565b600060018201612dcc57612dcc612d91565b5060010190565b600060208284031215612de557600080fd5b81516001600160401b03811115612dfb57600080fd5b6128b584828501612a68565b600081518084526020808501808196508360051b8101915082860160005b85811015612e4f578284038952612e3d8483516124f1565b98850198935090840190600101612e25565b5091979650505050505050565b60a081526000612e6f60a08301886124f1565b8281036020840152612e8181886124f1565b90508281036040840152612e958187612e07565b6001600160e01b03198616606085015283810360808501529050612eb981856124f1565b98975050505050505050565b805160208201516001600160e01b03198082169291906004831015612ef45780818460040360031b1b83161693505b505050919050565b6000806040808486031215612f1057600080fd5b8351612f1b81612210565b809350506020808501516001600160401b0380821115612f3a57600080fd5b818701915087601f830112612f4e57600080fd5b8151612f5c61232e8261237e565b81815260059190911b8301840190848101908a831115612f7b57600080fd5b8585015b83811015612fff57805185811115612f975760008081fd5b8601808d03601f1901891315612fad5760008081fd5b612fb56122a1565b8882015161ffff81168114612fca5760008081fd5b8152818a015187811115612fde5760008081fd5b612fec8f8b83860101612a68565b828b015250845250918601918601612f7f565b50809750505050505050509250929050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561307b57888303603f190185528151805161ffff168452870151878401879052613068878501826124f1565b9588019593505090860190600101613038565b509098975050505050505050565b8181038181111561033657610336612d91565b600080858511156130ac57600080fd5b838611156130b957600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f8301126130e757600080fd5b815160206130f761232e8361237e565b82815260059290921b8401810191818101908684111561311657600080fd5b8286015b848110156124355780516001600160401b038111156131395760008081fd5b6131478986838b0101612a68565b84525091830191830161311a565b60006020828403121561316757600080fd5b81516001600160401b038082111561317e57600080fd5b908301906060828603121561319257600080fd5b6040516060810181811083821117156131ad576131ad61228b565b60405282516131bb816129e6565b81526020830151828111156131cf57600080fd5b6131db878286016130d6565b6020830152506040830151828111156131f357600080fd5b6131ff87828601612a68565b60408301525095945050505050565b60018060a01b03815116825260006020820151606060208501526132356060850182612e07565b905060408301518482036040860152612d8882826124f1565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b828110156132a357603f1988860301845261329185835161320e565b94509285019290850190600101613275565b5092979650505050505050565b85151581526000602060018060a01b03871681840152604060a0818501526132db60a0850188612e07565b84810360608601526132ed81886124f1565b905084810360808601528086518083528483019150848160051b84010185890160005b8381101561335957858303601f19018552815180516001600160e01b0319168452880151888401889052613346888501826124f1565b9589019593505090870190600101613310565b50909d9c50505050505050505050505050565b6001600160a01b038616815260a06020820181905260009061339090830187612e07565b8281036040840152612e9581876124f1565b600080600080600060a086880312156133ba57600080fd5b85516133c5816129e6565b60208701519095506001600160401b03808211156133e257600080fd5b6133ee89838a016130d6565b9550604088015191508082111561340457600080fd5b61341089838a01612a68565b94506060880151915061342282612210565b60808801519193508082111561343757600080fd5b5061344488828901612a68565b9150509295509295909350565b602081526000612074602083018461320e565b600083516134768184602088016124cd565b83519083019061348a8183602088016124cd565b01949350505050565b6000602082840312156134a557600080fd5b815161207481612b1b565b601f8211156134fa57600081815260208120601f850160051c810160208610156134d75750805b601f850160051c820191505b818110156134f6578281556001016134e3565b5050505b505050565b81516001600160401b038111156135185761351861228b565b61352c816135268454612a18565b846134b0565b602080601f83116001811461356157600084156135495750858301515b600019600386901b1c1916600185901b1785556134f6565b600085815260208120601f198616915b8281101561359057888601518255948401946001909101908401613571565b50858210156135ae5787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212208634c5d4af4c93d564dd74cda8148bbcaaca136185b435687daeec24214a434164736f6c63430008110033", + "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", "devdoc": { "kind": "dev", "methods": { @@ -718,7 +695,7 @@ "storageLayout": { "storage": [ { - "astId": 444, + "astId": 7, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "_owner", "offset": 0, @@ -726,7 +703,7 @@ "type": "t_address" }, { - "astId": 18565, + "astId": 1511, "contract": "contracts/utils/UniversalResolver.sol:UniversalResolver", "label": "batchGatewayURLs", "offset": 0, diff --git a/deployments/mainnet/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json b/deployments/mainnet/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.json new file mode 100644 index 00000000..068c6c5c --- /dev/null +++ b/deployments/mainnet/solcInputs/b8a92c9207ae2a5ea22df4d7303f97f4.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 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 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" + }, + "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