diff --git a/deployments/holesky/ReverseRegistrar.json b/deployments/holesky/ReverseRegistrar.json index 562a151c..71c597ee 100644 --- a/deployments/holesky/ReverseRegistrar.json +++ b/deployments/holesky/ReverseRegistrar.json @@ -1,5 +1,5 @@ { - "address": "0x132AC0B116a73add4225029D1951A9A707Ef673f", + "address": "0x65EE0b0B030a76c95a7ff046C0e0c8f7A2d1B004", "abi": [ { "inputs": [ @@ -12,6 +12,31 @@ "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "ResolverAddressZero", + "type": "error" + }, + { + "inputs": [], + "name": "SignatureExpired", + "type": "error" + }, + { + "inputs": [], + "name": "SignatureExpiryTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorised", + "type": "error" + }, { "anonymous": false, "inputs": [ @@ -36,7 +61,7 @@ "inputs": [ { "indexed": true, - "internalType": "contract NameResolver", + "internalType": "address", "name": "resolver", "type": "address" } @@ -130,6 +155,45 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "signatureExpiry", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "name": "claimForAddrWithSignature", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -178,7 +242,7 @@ "name": "defaultResolver", "outputs": [ { - "internalType": "contract NameResolver", + "internalType": "contract INameSetterResolver", "name": "", "type": "address" } @@ -322,6 +386,69 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "signatureExpiry", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + } + ], + "name": "setNameForAddrWithSignature", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -336,91 +463,139 @@ "type": "function" } ], - "transactionHash": "0xacaf9395cf9248d931d6c5188bca9b35be7c91e7b696aa6fd1c89fddc2d868c7", + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", "receipt": { "to": null, - "from": "0x4Fe4e666Be5752f1FdD210F4Ab5DE2Cc26e3E0e8", - "contractAddress": "0x132AC0B116a73add4225029D1951A9A707Ef673f", - "transactionIndex": 1, - "gasUsed": "825844", - "logsBloom": "0x00000000000000000000000000000800000000000000200000800000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000001000000000000000000000000000000000000020002000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x03bb6d95d7348a02c01f3b4117551b1cdcc2907993d9454678d477e7750ca3c1", - "transactionHash": "0xacaf9395cf9248d931d6c5188bca9b35be7c91e7b696aa6fd1c89fddc2d868c7", + "from": "0x0F32b753aFc8ABad9Ca6fE589F707755f4df2353", + "contractAddress": "0x65EE0b0B030a76c95a7ff046C0e0c8f7A2d1B004", + "transactionIndex": 59, + "gasUsed": "1335580", + "logsBloom": "0x2001000000000000000000000000080000000000000000000080000000000000000000000000000000000000000000000000000000041008000800000002000000000000000000004000080000800000000100000000000000000080000000000000000002000200000000000000080000000000000000000000000000000040000001000000000000000000000400000000000000000020000000000010000000000000000004000000001000000000000400000200000000a000040000000000000000000000000000000000005000000000000000000000100000000020080000000000000000000080000100000000000000001000020000000000000000", + "blockHash": "0xf4467285c82dd52b30ea1fc7b84ed8ad887815ec409ef06c978d76cf14890131", + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", "logs": [ { - "transactionIndex": 1, - "blockNumber": 814551, - "transactionHash": "0xacaf9395cf9248d931d6c5188bca9b35be7c91e7b696aa6fd1c89fddc2d868c7", - "address": "0x132AC0B116a73add4225029D1951A9A707Ef673f", + "transactionIndex": 59, + "blockNumber": 2602779, + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", + "address": "0x65EE0b0B030a76c95a7ff046C0e0c8f7A2d1B004", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000004fe4e666be5752f1fdd210f4ab5de2cc26e3e0e8" + "0x0000000000000000000000000f32b753afc8abad9ca6fe589f707755f4df2353" ], "data": "0x", - "logIndex": 1, - "blockHash": "0x03bb6d95d7348a02c01f3b4117551b1cdcc2907993d9454678d477e7750ca3c1" + "logIndex": 141, + "blockHash": "0xf4467285c82dd52b30ea1fc7b84ed8ad887815ec409ef06c978d76cf14890131" + }, + { + "transactionIndex": 59, + "blockNumber": 2602779, + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", + "address": "0x132AC0B116a73add4225029D1951A9A707Ef673f", + "topics": [ + "0x6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e92", + "0x00000000000000000000000065ee0b0b030a76c95a7ff046c0e0c8f7a2d1b004", + "0xff68b6c4bf3a08168da505928a0b66a81bb356ad280b788f9734afbb72a32e43" + ], + "data": "0x", + "logIndex": 142, + "blockHash": "0xf4467285c82dd52b30ea1fc7b84ed8ad887815ec409ef06c978d76cf14890131" + }, + { + "transactionIndex": 59, + "blockNumber": 2602779, + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", + "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + "topics": [ + "0xce0457fe73731f824cc272376169235128c118b49d344817417c6d108d155e82", + "0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2", + "0x0e89437d21b5de1f93104889f3060f36ca239b8c936157120c450ee5731aa0bb" + ], + "data": "0x0000000000000000000000000f32b753afc8abad9ca6fe589f707755f4df2353", + "logIndex": 143, + "blockHash": "0xf4467285c82dd52b30ea1fc7b84ed8ad887815ec409ef06c978d76cf14890131" + }, + { + "transactionIndex": 59, + "blockNumber": 2602779, + "transactionHash": "0x27eee7a7194ddda1354ac4c9c86af96dbdb1e450d4008a6f6a306ed02a63507d", + "address": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + "topics": [ + "0x335721b01866dc23fbee8b6b2c7b1e14d6f05c28cd35a2c934239f94095602a0", + "0xff68b6c4bf3a08168da505928a0b66a81bb356ad280b788f9734afbb72a32e43" + ], + "data": "0x0000000000000000000000009010a27463717360cad99cea8bd39b8705cca238", + "logIndex": 144, + "blockHash": "0xf4467285c82dd52b30ea1fc7b84ed8ad887815ec409ef06c978d76cf14890131" } ], - "blockNumber": 814551, - "cumulativeGasUsed": "899641", + "blockNumber": 2602779, + "cumulativeGasUsed": "11001108", "status": 1, "byzantium": true }, "args": [ "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" ], - "numDeployments": 1, - "solcInputHash": "2286d90f0970dc1d34ef122ce5b9cee1", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ENS\",\"name\":\"ensAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"ControllerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"contract NameResolver\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"DefaultResolverChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ReverseClaimed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"claimForAddr\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"claimWithResolver\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"controllers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultResolver\",\"outputs\":[{\"internalType\":\"contract NameResolver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ens\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"node\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setDefaultResolver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setNameForAddr\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"claim(address)\":{\"details\":\"Transfers ownership of the reverse ENS record associated with the calling account.\",\"params\":{\"owner\":\"The address to set as the owner of the reverse record in ENS.\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record.\"}},\"claimForAddr(address,address,address)\":{\"details\":\"Transfers ownership of the reverse ENS record associated with the calling account.\",\"params\":{\"addr\":\"The reverse record to set\",\"owner\":\"The address to set as the owner of the reverse record in ENS.\",\"resolver\":\"The resolver of the reverse node\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record.\"}},\"claimWithResolver(address,address)\":{\"details\":\"Transfers ownership of the reverse ENS record associated with the calling account.\",\"params\":{\"owner\":\"The address to set as the owner of the reverse record in ENS.\",\"resolver\":\"The address of the resolver to set; 0 to leave unchanged.\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record.\"}},\"constructor\":{\"details\":\"Constructor\",\"params\":{\"ensAddr\":\"The address of the ENS registry.\"}},\"node(address)\":{\"details\":\"Returns the node hash for a given account's reverse records.\",\"params\":{\"addr\":\"The address to hash\"},\"returns\":{\"_0\":\"The ENS node hash.\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setName(string)\":{\"details\":\"Sets the `name()` record for the reverse ENS record associated with the calling account. First updates the resolver to the default reverse resolver if necessary.\",\"params\":{\"name\":\"The name to set for this address.\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record.\"}},\"setNameForAddr(address,address,address,string)\":{\"details\":\"Sets the `name()` record for the reverse ENS record associated with the account provided. Updates the resolver to a designated resolver Only callable by controllers and authorised users\",\"params\":{\"addr\":\"The reverse record to set\",\"name\":\"The name to set for this address.\",\"owner\":\"The owner of the reverse node\",\"resolver\":\"The resolver of the reverse node\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record.\"}},\"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\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/reverseRegistrar/ReverseRegistrar.sol\":\"ReverseRegistrar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/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\"},\"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/reverseRegistrar/IReverseRegistrar.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\ninterface IReverseRegistrar {\\n function setDefaultResolver(address resolver) external;\\n\\n function claim(address owner) external returns (bytes32);\\n\\n function claimForAddr(\\n address addr,\\n address owner,\\n address resolver\\n ) external returns (bytes32);\\n\\n function claimWithResolver(\\n address owner,\\n address resolver\\n ) external returns (bytes32);\\n\\n function setName(string memory name) external returns (bytes32);\\n\\n function setNameForAddr(\\n address addr,\\n address owner,\\n address resolver,\\n string memory name\\n ) external returns (bytes32);\\n\\n function node(address addr) external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0x83adfcf6da72b1bcd1e3ac387afe5fc7fdf7f2ac28b7601544d2ca4b9d45d159\"},\"contracts/reverseRegistrar/ReverseRegistrar.sol\":{\"content\":\"pragma solidity >=0.8.4;\\n\\nimport \\\"../registry/ENS.sol\\\";\\nimport \\\"./IReverseRegistrar.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"../root/Controllable.sol\\\";\\n\\nabstract contract NameResolver {\\n function setName(bytes32 node, string memory name) public virtual;\\n}\\n\\nbytes32 constant lookup = 0x3031323334353637383961626364656600000000000000000000000000000000;\\n\\nbytes32 constant ADDR_REVERSE_NODE = 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\\n\\n// namehash('addr.reverse')\\n\\ncontract ReverseRegistrar is Ownable, Controllable, IReverseRegistrar {\\n ENS public immutable ens;\\n NameResolver public defaultResolver;\\n\\n event ReverseClaimed(address indexed addr, bytes32 indexed node);\\n event DefaultResolverChanged(NameResolver indexed resolver);\\n\\n /**\\n * @dev Constructor\\n * @param ensAddr The address of the ENS registry.\\n */\\n constructor(ENS ensAddr) {\\n ens = ensAddr;\\n\\n // Assign ownership of the reverse record to our deployer\\n ReverseRegistrar oldRegistrar = ReverseRegistrar(\\n ensAddr.owner(ADDR_REVERSE_NODE)\\n );\\n if (address(oldRegistrar) != address(0x0)) {\\n oldRegistrar.claim(msg.sender);\\n }\\n }\\n\\n modifier authorised(address addr) {\\n require(\\n addr == msg.sender ||\\n controllers[msg.sender] ||\\n ens.isApprovedForAll(addr, msg.sender) ||\\n ownsContract(addr),\\n \\\"ReverseRegistrar: Caller is not a controller or authorised by address or the address itself\\\"\\n );\\n _;\\n }\\n\\n function setDefaultResolver(address resolver) public override onlyOwner {\\n require(\\n address(resolver) != address(0),\\n \\\"ReverseRegistrar: Resolver address must not be 0\\\"\\n );\\n defaultResolver = NameResolver(resolver);\\n emit DefaultResolverChanged(NameResolver(resolver));\\n }\\n\\n /**\\n * @dev Transfers ownership of the reverse ENS record associated with the\\n * calling account.\\n * @param owner The address to set as the owner of the reverse record in ENS.\\n * @return The ENS node hash of the reverse record.\\n */\\n function claim(address owner) public override returns (bytes32) {\\n return claimForAddr(msg.sender, owner, address(defaultResolver));\\n }\\n\\n /**\\n * @dev Transfers ownership of the reverse ENS record associated with the\\n * calling account.\\n * @param addr The reverse record to set\\n * @param owner The address to set as the owner of the reverse record in ENS.\\n * @param resolver The resolver of the reverse node\\n * @return The ENS node hash of the reverse record.\\n */\\n function claimForAddr(\\n address addr,\\n address owner,\\n address resolver\\n ) public override authorised(addr) returns (bytes32) {\\n bytes32 labelHash = sha3HexAddress(addr);\\n bytes32 reverseNode = keccak256(\\n abi.encodePacked(ADDR_REVERSE_NODE, labelHash)\\n );\\n emit ReverseClaimed(addr, reverseNode);\\n ens.setSubnodeRecord(ADDR_REVERSE_NODE, labelHash, owner, resolver, 0);\\n return reverseNode;\\n }\\n\\n /**\\n * @dev Transfers ownership of the reverse ENS record associated with the\\n * calling account.\\n * @param owner The address to set as the owner of the reverse record in ENS.\\n * @param resolver The address of the resolver to set; 0 to leave unchanged.\\n * @return The ENS node hash of the reverse record.\\n */\\n function claimWithResolver(\\n address owner,\\n address resolver\\n ) public override returns (bytes32) {\\n return claimForAddr(msg.sender, owner, resolver);\\n }\\n\\n /**\\n * @dev Sets the `name()` record for the reverse ENS record associated with\\n * the calling account. First updates the resolver to the default reverse\\n * resolver if necessary.\\n * @param name The name to set for this address.\\n * @return The ENS node hash of the reverse record.\\n */\\n function setName(string memory name) public override returns (bytes32) {\\n return\\n setNameForAddr(\\n msg.sender,\\n msg.sender,\\n address(defaultResolver),\\n name\\n );\\n }\\n\\n /**\\n * @dev Sets the `name()` record for the reverse ENS record associated with\\n * the account provided. Updates the resolver to a designated resolver\\n * Only callable by controllers and authorised users\\n * @param addr The reverse record to set\\n * @param owner The owner of the reverse node\\n * @param resolver The resolver of the reverse node\\n * @param name The name to set for this address.\\n * @return The ENS node hash of the reverse record.\\n */\\n function setNameForAddr(\\n address addr,\\n address owner,\\n address resolver,\\n string memory name\\n ) public override returns (bytes32) {\\n bytes32 node = claimForAddr(addr, owner, resolver);\\n NameResolver(resolver).setName(node, name);\\n return node;\\n }\\n\\n /**\\n * @dev Returns the node hash for a given account's reverse records.\\n * @param addr The address to hash\\n * @return The ENS node hash.\\n */\\n function node(address addr) public pure override returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(ADDR_REVERSE_NODE, sha3HexAddress(addr))\\n );\\n }\\n\\n /**\\n * @dev An optimised function to compute the sha3 of the lower-case\\n * hexadecimal representation of an Ethereum address.\\n * @param addr The address to hash\\n * @return ret The SHA3 hash of the lower-case hexadecimal encoding of the\\n * input address.\\n */\\n function sha3HexAddress(address addr) private pure returns (bytes32 ret) {\\n assembly {\\n for {\\n let i := 40\\n } gt(i, 0) {\\n\\n } {\\n i := sub(i, 1)\\n mstore8(i, byte(and(addr, 0xf), lookup))\\n addr := div(addr, 0x10)\\n i := sub(i, 1)\\n mstore8(i, byte(and(addr, 0xf), lookup))\\n addr := div(addr, 0x10)\\n }\\n\\n ret := keccak256(0, 40)\\n }\\n }\\n\\n function ownsContract(address addr) internal view returns (bool) {\\n try Ownable(addr).owner() returns (address owner) {\\n return owner == msg.sender;\\n } catch {\\n return false;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd57d28e5791b4b44650a00f5ef6c725af53698ec33faeeaa3591f0dbd939559a\"},\"contracts/root/Controllable.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\ncontract Controllable is Ownable {\\n mapping(address => bool) public controllers;\\n\\n event ControllerChanged(address indexed controller, bool enabled);\\n\\n modifier onlyController() {\\n require(\\n controllers[msg.sender],\\n \\\"Controllable: Caller is not a controller\\\"\\n );\\n _;\\n }\\n\\n function setController(address controller, bool enabled) public onlyOwner {\\n controllers[controller] = enabled;\\n emit ControllerChanged(controller, enabled);\\n }\\n}\\n\",\"keccak256\":\"0xb19b8c0fafe9ca2b4bf8aaafee486fa31437672e1e1977bdf84bfe03464969db\"}},\"version\":1}", - "bytecode": "0x60a060405234801561001057600080fd5b5060405162000f5338038062000f53833981016040819052610031916101b6565b61003a3361014e565b6001600160a01b03811660808190526040516302571be360e01b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152600091906302571be390602401602060405180830381865afa1580156100a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100ca91906101b6565b90506001600160a01b0381161561014757604051630f41a04d60e11b81523360048201526001600160a01b03821690631e83409a906024016020604051808303816000875af1158015610121573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014591906101da565b505b50506101f3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146101b357600080fd5b50565b6000602082840312156101c857600080fd5b81516101d38161019e565b9392505050565b6000602082840312156101ec57600080fd5b5051919050565b608051610d366200021d6000396000818161012d015281816102f001526105070152610d366000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063c66485b211610066578063c66485b2146101e1578063da8c229e146101f4578063e0dba60f14610227578063f2fde38b1461023a57600080fd5b80638da5cb5b146101aa578063bffbe61c146101bb578063c47f0027146101ce57600080fd5b806365669631116100c85780636566963114610167578063715018a61461017a5780637a806d6b14610184578063828eab0e1461019757600080fd5b80630f5a5466146100ef5780631e83409a146101155780633f15457f14610128575b600080fd5b6101026100fd366004610a25565b61024d565b6040519081526020015b60405180910390f35b610102610123366004610a5e565b610261565b61014f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161010c565b610102610175366004610a7b565b610283565b61018261056e565b005b610102610192366004610b82565b610582565b60025461014f906001600160a01b031681565b6000546001600160a01b031661014f565b6101026101c9366004610a5e565b610616565b6101026101dc366004610bf7565b610671565b6101826101ef366004610a5e565b61068e565b610217610202366004610a5e565b60016020526000908152604090205460ff1681565b604051901515815260200161010c565b610182610235366004610c42565b610769565b610182610248366004610a5e565b6107d0565b600061025a338484610283565b9392505050565b60025460009061027d90339084906001600160a01b0316610283565b92915050565b6000836001600160a01b0381163314806102ac57503360009081526001602052604090205460ff165b8061035b57506040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301523360248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c590604401602060405180830381865afa158015610337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610c70565b8061036a575061036a81610860565b6104075760405162461bcd60e51b815260206004820152605b60248201527f526576657273655265676973747261723a2043616c6c6572206973206e6f742060448201527f6120636f6e74726f6c6c6572206f7220617574686f726973656420627920616460648201527f6472657373206f7220746865206164647265737320697473656c660000000000608482015260a4015b60405180910390fd5b6000610412866108d9565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602080830191909152818301849052825180830384018152606090920192839052815191012091925081906001600160a01b038916907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040517f5ef2c7f00000000000000000000000000000000000000000000000000000000081527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018390526001600160a01b0387811660448301528681166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a401600060405180830381600087803b15801561054b57600080fd5b505af115801561055f573d6000803e3d6000fd5b50929998505050505050505050565b610576610959565b61058060006109b3565b565b600080610590868686610283565b6040517f773722130000000000000000000000000000000000000000000000000000000081529091506001600160a01b038516906377372213906105da9084908790600401610c8d565b600060405180830381600087803b1580156105f457600080fd5b505af1158015610608573d6000803e3d6000fd5b509298975050505050505050565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2610642836108d9565b604080516020810193909352820152606001604051602081830303815290604052805190602001209050919050565b60025460009061027d90339081906001600160a01b031685610582565b610696610959565b6001600160a01b0381166107125760405162461bcd60e51b815260206004820152603060248201527f526576657273655265676973747261723a205265736f6c76657220616464726560448201527f7373206d757374206e6f7420626520300000000000000000000000000000000060648201526084016103fe565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517feae17a84d9eb83d8c8eb317f9e7d64857bc363fa51674d996c023f4340c577cf90600090a250565b610771610959565b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f4c97694570a07277810af7e5669ffd5f6a2d6b74b6e9a274b8b870fd5114cf87910160405180910390a25050565b6107d8610959565b6001600160a01b0381166108545760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103fe565b61085d816109b3565b50565b6000816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108bc575060408051601f3d908101601f191682019092526108b991810190610ce3565b60015b6108c857506000919050565b6001600160a01b0316331492915050565b600060285b801561094d57600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601090920491600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a81536010830492506108de565b50506028600020919050565b6000546001600160a01b031633146105805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103fe565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461085d57600080fd5b60008060408385031215610a3857600080fd5b8235610a4381610a10565b91506020830135610a5381610a10565b809150509250929050565b600060208284031215610a7057600080fd5b813561025a81610a10565b600080600060608486031215610a9057600080fd5b8335610a9b81610a10565b92506020840135610aab81610a10565b91506040840135610abb81610a10565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610b0657600080fd5b813567ffffffffffffffff80821115610b2157610b21610ac6565b604051601f8301601f19908116603f01168101908282118183101715610b4957610b49610ac6565b81604052838152866020858801011115610b6257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215610b9857600080fd5b8435610ba381610a10565b93506020850135610bb381610a10565b92506040850135610bc381610a10565b9150606085013567ffffffffffffffff811115610bdf57600080fd5b610beb87828801610af5565b91505092959194509250565b600060208284031215610c0957600080fd5b813567ffffffffffffffff811115610c2057600080fd5b610c2c84828501610af5565b949350505050565b801515811461085d57600080fd5b60008060408385031215610c5557600080fd5b8235610c6081610a10565b91506020830135610a5381610c34565b600060208284031215610c8257600080fd5b815161025a81610c34565b82815260006020604081840152835180604085015260005b81811015610cc157858101830151858201606001528201610ca5565b506000606082860101526060601f19601f830116850101925050509392505050565b600060208284031215610cf557600080fd5b815161025a81610a1056fea2646970667358221220daae2d891af11b235f016443111e7af5d0e35047fc15f99c70bd6412d181638564736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638da5cb5b1161008c578063c66485b211610066578063c66485b2146101e1578063da8c229e146101f4578063e0dba60f14610227578063f2fde38b1461023a57600080fd5b80638da5cb5b146101aa578063bffbe61c146101bb578063c47f0027146101ce57600080fd5b806365669631116100c85780636566963114610167578063715018a61461017a5780637a806d6b14610184578063828eab0e1461019757600080fd5b80630f5a5466146100ef5780631e83409a146101155780633f15457f14610128575b600080fd5b6101026100fd366004610a25565b61024d565b6040519081526020015b60405180910390f35b610102610123366004610a5e565b610261565b61014f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161010c565b610102610175366004610a7b565b610283565b61018261056e565b005b610102610192366004610b82565b610582565b60025461014f906001600160a01b031681565b6000546001600160a01b031661014f565b6101026101c9366004610a5e565b610616565b6101026101dc366004610bf7565b610671565b6101826101ef366004610a5e565b61068e565b610217610202366004610a5e565b60016020526000908152604090205460ff1681565b604051901515815260200161010c565b610182610235366004610c42565b610769565b610182610248366004610a5e565b6107d0565b600061025a338484610283565b9392505050565b60025460009061027d90339084906001600160a01b0316610283565b92915050565b6000836001600160a01b0381163314806102ac57503360009081526001602052604090205460ff165b8061035b57506040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301523360248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c590604401602060405180830381865afa158015610337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610c70565b8061036a575061036a81610860565b6104075760405162461bcd60e51b815260206004820152605b60248201527f526576657273655265676973747261723a2043616c6c6572206973206e6f742060448201527f6120636f6e74726f6c6c6572206f7220617574686f726973656420627920616460648201527f6472657373206f7220746865206164647265737320697473656c660000000000608482015260a4015b60405180910390fd5b6000610412866108d9565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602080830191909152818301849052825180830384018152606090920192839052815191012091925081906001600160a01b038916907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040517f5ef2c7f00000000000000000000000000000000000000000000000000000000081527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018390526001600160a01b0387811660448301528681166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a401600060405180830381600087803b15801561054b57600080fd5b505af115801561055f573d6000803e3d6000fd5b50929998505050505050505050565b610576610959565b61058060006109b3565b565b600080610590868686610283565b6040517f773722130000000000000000000000000000000000000000000000000000000081529091506001600160a01b038516906377372213906105da9084908790600401610c8d565b600060405180830381600087803b1580156105f457600080fd5b505af1158015610608573d6000803e3d6000fd5b509298975050505050505050565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2610642836108d9565b604080516020810193909352820152606001604051602081830303815290604052805190602001209050919050565b60025460009061027d90339081906001600160a01b031685610582565b610696610959565b6001600160a01b0381166107125760405162461bcd60e51b815260206004820152603060248201527f526576657273655265676973747261723a205265736f6c76657220616464726560448201527f7373206d757374206e6f7420626520300000000000000000000000000000000060648201526084016103fe565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517feae17a84d9eb83d8c8eb317f9e7d64857bc363fa51674d996c023f4340c577cf90600090a250565b610771610959565b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f4c97694570a07277810af7e5669ffd5f6a2d6b74b6e9a274b8b870fd5114cf87910160405180910390a25050565b6107d8610959565b6001600160a01b0381166108545760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103fe565b61085d816109b3565b50565b6000816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156108bc575060408051601f3d908101601f191682019092526108b991810190610ce3565b60015b6108c857506000919050565b6001600160a01b0316331492915050565b600060285b801561094d57600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601090920491600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a81536010830492506108de565b50506028600020919050565b6000546001600160a01b031633146105805760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103fe565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038116811461085d57600080fd5b60008060408385031215610a3857600080fd5b8235610a4381610a10565b91506020830135610a5381610a10565b809150509250929050565b600060208284031215610a7057600080fd5b813561025a81610a10565b600080600060608486031215610a9057600080fd5b8335610a9b81610a10565b92506020840135610aab81610a10565b91506040840135610abb81610a10565b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610b0657600080fd5b813567ffffffffffffffff80821115610b2157610b21610ac6565b604051601f8301601f19908116603f01168101908282118183101715610b4957610b49610ac6565b81604052838152866020858801011115610b6257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060808587031215610b9857600080fd5b8435610ba381610a10565b93506020850135610bb381610a10565b92506040850135610bc381610a10565b9150606085013567ffffffffffffffff811115610bdf57600080fd5b610beb87828801610af5565b91505092959194509250565b600060208284031215610c0957600080fd5b813567ffffffffffffffff811115610c2057600080fd5b610c2c84828501610af5565b949350505050565b801515811461085d57600080fd5b60008060408385031215610c5557600080fd5b8235610c6081610a10565b91506020830135610a5381610c34565b600060208284031215610c8257600080fd5b815161025a81610c34565b82815260006020604081840152835180604085015260005b81811015610cc157858101830151858201606001528201610ca5565b506000606082860101526060601f19601f830116850101925050509392505050565b600060208284031215610cf557600080fd5b815161025a81610a1056fea2646970667358221220daae2d891af11b235f016443111e7af5d0e35047fc15f99c70bd6412d181638564736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "e27011e9521d1f56963a5ba6ba5278b4", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract ENS\",\"name\":\"ensAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ResolverAddressZero\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignatureExpiryTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorised\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"ControllerChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"DefaultResolverChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"node\",\"type\":\"bytes32\"}],\"name\":\"ReverseClaimed\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"claim\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"claimForAddr\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"signatureExpiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"claimForAddrWithSignature\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"claimWithResolver\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"controllers\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"defaultResolver\",\"outputs\":[{\"internalType\":\"contract INameSetterResolver\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ens\",\"outputs\":[{\"internalType\":\"contract ENS\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"node\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"controller\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"name\":\"setController\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"}],\"name\":\"setDefaultResolver\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setNameForAddr\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resolver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"signatureExpiry\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"}],\"name\":\"setNameForAddrWithSignature\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"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\":{\"claim(address)\":{\"params\":{\"owner\":\"The address to set as the owner of the reverse record in ENS.\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"claimForAddr(address,address,address)\":{\"params\":{\"addr\":\"The address to claim the reverse record for\",\"owner\":\"The address to set as the owner of the reverse record\",\"resolver\":\"The resolver of the reverse node\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"claimForAddrWithSignature(address,address,address,uint256,bytes)\":{\"params\":{\"addr\":\"The address to claim the reverse record for\",\"owner\":\"The address to set as the owner of the reverse record\",\"resolver\":\"The resolver of the reverse node\",\"signature\":\"The signature to authorise the claim\",\"signatureExpiry\":\"The expiry of the signature\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"claimWithResolver(address,address)\":{\"params\":{\"owner\":\"The address to set as the owner of the reverse record\",\"resolver\":\"The resolver of the reverse node\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"constructor\":{\"params\":{\"ensAddr\":\"The address of the ENS registry\"}},\"node(address)\":{\"params\":{\"addr\":\"The address to get the reverse node hash for\"},\"returns\":{\"_0\":\"The ENS node hash\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setDefaultResolver(address)\":{\"params\":{\"resolver\":\"The resolver to set\"}},\"setName(string)\":{\"params\":{\"name\":\"The name to set for the calling account\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"setNameForAddr(address,address,address,string)\":{\"params\":{\"addr\":\"The reverse record to set\",\"name\":\"The name to set for the provided address\",\"owner\":\"The owner of the reverse node\",\"resolver\":\"The resolver of the reverse node\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"setNameForAddrWithSignature(address,address,address,uint256,bytes,string)\":{\"params\":{\"addr\":\"The reverse record to set\",\"name\":\"The name to set for the provided address\",\"owner\":\"The owner of the reverse node\",\"resolver\":\"The resolver of the reverse node\",\"signature\":\"The signature to authorise the claim\",\"signatureExpiry\":\"The expiry of the signature\"},\"returns\":{\"_0\":\"The ENS node hash of the reverse record\"}},\"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.\"}},\"stateVariables\":{\"ADDR_REVERSE_NODE\":{\"details\":\"`namehash('addr.reverse')`\"}},\"title\":\"ENS Reverse Registrar\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidSignature()\":[{\"notice\":\"The signature is invalid\"}],\"ResolverAddressZero()\":[{\"notice\":\"Thrown when the resolver address is zero\"}],\"SignatureExpired()\":[{\"notice\":\"The signature has expired\"}],\"SignatureExpiryTooHigh()\":[{\"notice\":\"The signature expiry is too high\"}],\"Unauthorised()\":[{\"notice\":\"Thrown when the caller is not authorised to perform the action\"}]},\"events\":{\"DefaultResolverChanged(address)\":{\"notice\":\"Emitted when the default resolver is changed.\"},\"ReverseClaimed(address,bytes32)\":{\"notice\":\"Emitted when a reverse record is claimed.\"}},\"kind\":\"user\",\"methods\":{\"claim(address)\":{\"notice\":\"Transfers ownership of the reverse ENS record associated with the calling account.\"},\"claimForAddr(address,address,address)\":{\"notice\":\"Transfers ownership of the reverse ENS record associated with the addr provided account.\"},\"claimForAddrWithSignature(address,address,address,uint256,bytes)\":{\"notice\":\"Transfers ownership of the reverse ENS record associated with the addr provided account using a signature to authorise.\"},\"claimWithResolver(address,address)\":{\"notice\":\"Transfers ownership of the reverse ENS record associated with the calling account.\"},\"constructor\":{\"notice\":\"Sets the ENS registry and claims `addr.reverse`\"},\"defaultResolver()\":{\"notice\":\"The default resolver\"},\"ens()\":{\"notice\":\"The ENS registry\"},\"node(address)\":{\"notice\":\"Returns the ENS node hash for the reverse record associated with the addr provided account.\"},\"setDefaultResolver(address)\":{\"notice\":\"Sets the default resolver\"},\"setName(string)\":{\"notice\":\"Sets the `name()` record for the reverse ENS record associated with the calling account, and updates the resolver to the default reverse resolver.\"},\"setNameForAddr(address,address,address,string)\":{\"notice\":\"Sets the `name()` record for the reverse ENS record associated with the addr provided account, and updates the resolver to the resolver provided.\"},\"setNameForAddrWithSignature(address,address,address,uint256,bytes,string)\":{\"notice\":\"Sets the `name()` record for the reverse ENS record associated with the addr provided account using a signature to authorise, and updates the resolver to the resolver provided.\"}},\"notice\":\"The registrar for reverse records on ENS\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/reverseRegistrar/ReverseRegistrar.sol\":\"ReverseRegistrar\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC1271.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC1271 standard signature validation method for\\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC1271 {\\n /**\\n * @dev Should return whether the signature provided is valid for the provided data\\n * @param hash Hash of the data to be signed\\n * @param signature Signature byte array associated with _data\\n */\\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\\n}\\n\",\"keccak256\":\"0x0705a4b1b86d7b0bd8432118f226ba139c44b9dcaba0a6eafba2dd7d0639c544\",\"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/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toString(int256 value) internal pure returns (string memory) {\\n return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n mstore(0x1c, hash)\\n message := keccak256(0x00, 0x3c)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n data := keccak256(ptr, 0x42)\\n }\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n * `validator` and `data` according to the version 0 of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../../interfaces/IERC1271.sol\\\";\\n\\n/**\\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\\n * Argent and Gnosis Safe.\\n *\\n * _Available since v4.1._\\n */\\nlibrary SignatureChecker {\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\\n return\\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\\n isValidERC1271SignatureNow(signer, hash, signature);\\n }\\n\\n /**\\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\\n * against the signer smart contract using ERC1271.\\n *\\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\\n */\\n function isValidERC1271SignatureNow(\\n address signer,\\n bytes32 hash,\\n bytes memory signature\\n ) internal view returns (bool) {\\n (bool success, bytes memory result) = signer.staticcall(\\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\\n );\\n return (success &&\\n result.length >= 32 &&\\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\\n }\\n}\\n\",\"keccak256\":\"0x3af3ca86df39aac39a0514c84459d691434a108d2151c8ce9d69f32e315cab80\",\"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\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"contracts/registry/ENS.sol\":{\"content\":\"//SPDX-License-Identifier: MIT\\npragma 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\":\"0x8e208b44d5dbf22552fe72d79b45c640855b84fbc9ee21f4c3bb4bfe81cbe8db\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/IReverseRegistrar.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\n/// @notice Interface for the reverse registrar\\ninterface IReverseRegistrar {\\n /// @notice Emitted when a reverse record is claimed.\\n /// @param addr The address that the reverse record is claimed for\\n /// @param node The ENS node hash of the reverse record\\n event ReverseClaimed(address indexed addr, bytes32 indexed node);\\n\\n /// @notice Emitted when the default resolver is changed.\\n /// @param resolver The resolver that was set\\n event DefaultResolverChanged(address indexed resolver);\\n\\n /// @notice Thrown when the caller is not authorised to perform the action\\n error Unauthorised();\\n\\n /// @notice Thrown when the resolver address is zero\\n error ResolverAddressZero();\\n\\n /// @notice Sets the default resolver\\n /// @param resolver The resolver to set\\n function setDefaultResolver(address resolver) external;\\n\\n /// @notice Transfers ownership of the reverse ENS record associated with the\\n /// calling account.\\n /// @param owner The address to set as the owner of the reverse record in ENS.\\n /// @return The ENS node hash of the reverse record\\n function claim(address owner) external returns (bytes32);\\n\\n /// @notice Transfers ownership of the reverse ENS record associated with the\\n /// addr provided account.\\n /// @param addr The address to claim the reverse record for\\n /// @param owner The address to set as the owner of the reverse record\\n /// @param resolver The resolver of the reverse node\\n /// @return The ENS node hash of the reverse record\\n function claimForAddr(\\n address addr,\\n address owner,\\n address resolver\\n ) external returns (bytes32);\\n\\n /// @notice Transfers ownership of the reverse ENS record associated with the\\n /// addr provided account using a signature to authorise.\\n /// @param addr The address to claim the reverse record for\\n /// @param owner The address to set as the owner of the reverse record\\n /// @param resolver The resolver of the reverse node\\n /// @param signatureExpiry The expiry of the signature\\n /// @param signature The signature to authorise the claim\\n /// @return The ENS node hash of the reverse record\\n function claimForAddrWithSignature(\\n address addr,\\n address owner,\\n address resolver,\\n uint256 signatureExpiry,\\n bytes calldata signature\\n ) external returns (bytes32);\\n\\n /// @notice Transfers ownership of the reverse ENS record associated with the\\n /// calling account.\\n /// @param owner The address to set as the owner of the reverse record\\n /// @param resolver The resolver of the reverse node\\n /// @return The ENS node hash of the reverse record\\n function claimWithResolver(\\n address owner,\\n address resolver\\n ) external returns (bytes32);\\n\\n /// @notice Sets the `name()` record for the reverse ENS record associated\\n /// with the calling account, and updates the resolver to the\\n /// default reverse resolver.\\n /// @param name The name to set for the calling account\\n /// @return The ENS node hash of the reverse record\\n function setName(string memory name) external returns (bytes32);\\n\\n /// @notice Sets the `name()` record for the reverse ENS record associated\\n /// with the addr provided account, and updates the resolver to the\\n /// resolver provided.\\n /// @param addr The reverse record to set\\n /// @param owner The owner of the reverse node\\n /// @param resolver The resolver of the reverse node\\n /// @param name The name to set for the provided address\\n /// @return The ENS node hash of the reverse record\\n function setNameForAddr(\\n address addr,\\n address owner,\\n address resolver,\\n string memory name\\n ) external returns (bytes32);\\n\\n /// @notice Sets the `name()` record for the reverse ENS record associated\\n /// with the addr provided account using a signature to authorise,\\n /// and updates the resolver to the resolver provided.\\n /// @param addr The reverse record to set\\n /// @param owner The owner of the reverse node\\n /// @param resolver The resolver of the reverse node\\n /// @param signatureExpiry The expiry of the signature\\n /// @param signature The signature to authorise the claim\\n /// @param name The name to set for the provided address\\n /// @return The ENS node hash of the reverse record\\n function setNameForAddrWithSignature(\\n address addr,\\n address owner,\\n address resolver,\\n uint256 signatureExpiry,\\n bytes calldata signature,\\n string memory name\\n ) external returns (bytes32);\\n\\n /// @notice Returns the ENS node hash for the reverse record associated with\\n /// the addr provided account.\\n /// @param addr The address to get the reverse node hash for\\n /// @return The ENS node hash\\n function node(address addr) external pure returns (bytes32);\\n}\\n\",\"keccak256\":\"0x78754404ae6726501aa3b2c234167c3696237a012ca58aabe3e5356232a0bdbf\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/ReverseRegistrar.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\nimport {Ownable} from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {ERC165} from \\\"@openzeppelin/contracts/utils/introspection/ERC165.sol\\\";\\n\\nimport {ENS} from \\\"../registry/ENS.sol\\\";\\nimport {Controllable} from \\\"../root/Controllable.sol\\\";\\nimport {AddressUtils} from \\\"../utils/AddressUtils.sol\\\";\\n\\nimport {IReverseRegistrar} from \\\"./IReverseRegistrar.sol\\\";\\nimport {SignatureUtils} from \\\"./SignatureUtils.sol\\\";\\n\\ninterface INameSetterResolver {\\n function setName(bytes32 node, string memory name) external;\\n}\\n\\n/// @title ENS Reverse Registrar\\n/// @notice The registrar for reverse records on ENS\\ncontract ReverseRegistrar is Ownable, Controllable, ERC165, IReverseRegistrar {\\n using SignatureUtils for bytes;\\n using ECDSA for bytes32;\\n using AddressUtils for address;\\n\\n /// @dev `namehash('addr.reverse')`\\n bytes32 constant ADDR_REVERSE_NODE =\\n 0x91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2;\\n\\n /// @notice The ENS registry\\n ENS public immutable ens;\\n\\n /// @notice The default resolver\\n INameSetterResolver public defaultResolver;\\n\\n /// @notice Sets the ENS registry and claims `addr.reverse`\\n /// @param ensAddr The address of the ENS registry\\n constructor(ENS ensAddr) {\\n ens = ensAddr;\\n\\n // Assign ownership of the reverse record to our deployer\\n ReverseRegistrar oldRegistrar = ReverseRegistrar(\\n ensAddr.owner(ADDR_REVERSE_NODE)\\n );\\n if (address(oldRegistrar) != address(0x0)) {\\n oldRegistrar.claim(msg.sender);\\n }\\n }\\n\\n /// @notice Modifier to check if the caller is authorised to perform an action.\\n /// @param addr The address to check\\n modifier authorised(address addr) {\\n if (\\n addr != msg.sender &&\\n !controllers[msg.sender] &&\\n !ens.isApprovedForAll(addr, msg.sender) &&\\n !ownsContract(addr)\\n ) {\\n revert Unauthorised();\\n }\\n _;\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function setDefaultResolver(address resolver) public override onlyOwner {\\n if (address(resolver) == address(0)) revert ResolverAddressZero();\\n defaultResolver = INameSetterResolver(resolver);\\n emit DefaultResolverChanged(resolver);\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function claim(address owner) public override returns (bytes32) {\\n return claimForAddr(msg.sender, owner, address(defaultResolver));\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function claimForAddr(\\n address addr,\\n address owner,\\n address resolver\\n ) public override authorised(addr) returns (bytes32) {\\n bytes32 labelHash = addr.sha3HexAddress();\\n bytes32 reverseNode = keccak256(\\n abi.encodePacked(ADDR_REVERSE_NODE, labelHash)\\n );\\n emit ReverseClaimed(addr, reverseNode);\\n ens.setSubnodeRecord(ADDR_REVERSE_NODE, labelHash, owner, resolver, 0);\\n return reverseNode;\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function claimForAddrWithSignature(\\n address addr,\\n address owner,\\n address resolver,\\n uint256 signatureExpiry,\\n bytes memory signature\\n ) public override returns (bytes32) {\\n bytes32 labelHash = addr.sha3HexAddress();\\n bytes32 reverseNode = keccak256(\\n abi.encodePacked(ADDR_REVERSE_NODE, labelHash)\\n );\\n\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n IReverseRegistrar.claimForAddrWithSignature.selector,\\n addr,\\n owner,\\n resolver,\\n signatureExpiry\\n )\\n );\\n\\n bytes32 message = hash.toEthSignedMessageHash();\\n\\n signature.validateSignatureWithExpiry(addr, message, signatureExpiry);\\n\\n emit ReverseClaimed(addr, reverseNode);\\n ens.setSubnodeRecord(ADDR_REVERSE_NODE, labelHash, owner, resolver, 0);\\n return reverseNode;\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function claimWithResolver(\\n address owner,\\n address resolver\\n ) public override returns (bytes32) {\\n return claimForAddr(msg.sender, owner, resolver);\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function setName(string calldata name) public override returns (bytes32) {\\n return\\n setNameForAddr(\\n msg.sender,\\n msg.sender,\\n address(defaultResolver),\\n name\\n );\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function setNameForAddr(\\n address addr,\\n address owner,\\n address resolver,\\n string calldata name\\n ) public override returns (bytes32) {\\n bytes32 node = claimForAddr(addr, owner, resolver);\\n INameSetterResolver(resolver).setName(node, name);\\n return node;\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function setNameForAddrWithSignature(\\n address addr,\\n address owner,\\n address resolver,\\n uint256 signatureExpiry,\\n bytes memory signature,\\n string calldata name\\n ) public override returns (bytes32) {\\n bytes32 node = claimForAddrWithSignature(\\n addr,\\n owner,\\n resolver,\\n signatureExpiry,\\n signature\\n );\\n INameSetterResolver(resolver).setName(node, name);\\n return node;\\n }\\n\\n /// @inheritdoc IReverseRegistrar\\n function node(address addr) public pure override returns (bytes32) {\\n return\\n keccak256(\\n abi.encodePacked(ADDR_REVERSE_NODE, addr.sha3HexAddress())\\n );\\n }\\n\\n /// @dev Checks if the provided address is a contract and is owned by the\\n /// caller.\\n function ownsContract(address addr) internal view returns (bool) {\\n if (addr.code.length == 0) return false;\\n try Ownable(addr).owner() returns (address owner) {\\n return owner == msg.sender;\\n } catch (bytes memory /* lowLevelData */) {\\n return false;\\n }\\n }\\n\\n /// @inheritdoc ERC165\\n function supportsInterface(\\n bytes4 interfaceID\\n ) public view override(ERC165) returns (bool) {\\n return\\n interfaceID == type(IReverseRegistrar).interfaceId ||\\n super.supportsInterface(interfaceID);\\n }\\n}\\n\",\"keccak256\":\"0xf4c618d5bf2d232c5e3afcae378c079b4b491097df3e6496eb93a5ba1c5d9da9\",\"license\":\"MIT\"},\"contracts/reverseRegistrar/SignatureUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.4;\\n\\nimport {SignatureChecker} from \\\"@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol\\\";\\n\\n/// @notice Utility functions for validating signatures with expiry\\nlibrary SignatureUtils {\\n /// @notice The signature is invalid\\n error InvalidSignature();\\n /// @notice The signature expiry is too high\\n error SignatureExpiryTooHigh();\\n /// @notice The signature has expired\\n error SignatureExpired();\\n\\n /// @notice Validates a signature with expiry\\n /// @param signature The signature to validate\\n /// @param addr The address that signed the message\\n /// @param message The message that was signed\\n /// @param signatureExpiry The expiry of the signature\\n function validateSignatureWithExpiry(\\n bytes memory signature,\\n address addr,\\n bytes32 message,\\n uint256 signatureExpiry\\n ) internal view {\\n if (!SignatureChecker.isValidSignatureNow(addr, message, signature))\\n revert InvalidSignature();\\n if (signatureExpiry < block.timestamp) revert SignatureExpired();\\n if (signatureExpiry > block.timestamp + 1 hours)\\n revert SignatureExpiryTooHigh();\\n }\\n}\\n\",\"keccak256\":\"0xba80f33df47e87ccdcfe43f67afb793158b42f5db813394643ad66d58abd0093\",\"license\":\"MIT\"},\"contracts/root/Controllable.sol\":{\"content\":\"pragma solidity ^0.8.4;\\n\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\n\\ncontract Controllable is Ownable {\\n mapping(address => bool) public controllers;\\n\\n event ControllerChanged(address indexed controller, bool enabled);\\n\\n modifier onlyController() {\\n require(\\n controllers[msg.sender],\\n \\\"Controllable: Caller is not a controller\\\"\\n );\\n _;\\n }\\n\\n function setController(address controller, bool enabled) public onlyOwner {\\n controllers[controller] = enabled;\\n emit ControllerChanged(controller, enabled);\\n }\\n}\\n\",\"keccak256\":\"0xb19b8c0fafe9ca2b4bf8aaafee486fa31437672e1e1977bdf84bfe03464969db\"},\"contracts/utils/AddressUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.13;\\n\\nlibrary AddressUtils {\\n // This is the hex encoding of the string 'abcdefghijklmnopqrstuvwxyz'\\n // It is used as a constant to lookup the characters of the hex address\\n bytes32 constant lookup =\\n 0x3031323334353637383961626364656600000000000000000000000000000000;\\n\\n /**\\n * @dev An optimised function to compute the sha3 of the lower-case\\n * hexadecimal representation of an Ethereum address.\\n * @param addr The address to hash\\n * @return ret The SHA3 hash of the lower-case hexadecimal encoding of the\\n * input address.\\n */\\n function sha3HexAddress(address addr) internal pure returns (bytes32 ret) {\\n assembly {\\n for {\\n let i := 40\\n } gt(i, 0) {\\n\\n } {\\n i := sub(i, 1)\\n mstore8(i, byte(and(addr, 0xf), lookup))\\n addr := div(addr, 0x10)\\n i := sub(i, 1)\\n mstore8(i, byte(and(addr, 0xf), lookup))\\n addr := div(addr, 0x10)\\n }\\n\\n ret := keccak256(0, 40)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0e54b564d675e257f9c1e9ae59d2ebec651dcf468865cecd45ea341dcca83ca5\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a06040523480156200001157600080fd5b50604051620017bc380380620017bc8339810160408190526200003491620001c4565b6200003f336200015b565b6001600160a01b03811660808190526040516302571be360e01b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152600091906302571be390602401602060405180830381865afa158015620000ac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d29190620001c4565b90506001600160a01b038116156200015357604051630f41a04d60e11b81523360048201526001600160a01b03821690631e83409a906024016020604051808303816000875af11580156200012b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001519190620001eb565b505b505062000205565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b0381168114620001c157600080fd5b50565b600060208284031215620001d757600080fd5b8151620001e481620001ab565b9392505050565b600060208284031215620001fe57600080fd5b5051919050565b60805161158662000236600039600081816101940152818161050a015281816105e5015261078b01526115866000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063828eab0e116100b2578063c66485b211610081578063e0801e9a11610066578063e0801e9a1461027e578063e0dba60f14610291578063f2fde38b146102a457600080fd5b8063c66485b214610248578063da8c229e1461025b57600080fd5b8063828eab0e146101fe5780638da5cb5b14610211578063bffbe61c14610222578063c47f00271461023557600080fd5b80633f15457f116100ee5780633f15457f1461018f57806365669631146101ce578063715018a6146101e15780637a806d6b146101eb57600080fd5b806301ffc9a7146101205780630f5a5466146101485780631e83409a1461016957806334d671991461017c575b600080fd5b61013361012e36600461102c565b6102b7565b60405190151581526020015b60405180910390f35b61015b61015636600461106b565b610320565b60405190815260200161013f565b61015b6101773660046110a4565b610334565b61015b61018a366004611164565b610350565b6101b67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161013f565b61015b6101dc3660046111e3565b610574565b6101e96107f3565b005b61015b6101f9366004611270565b610807565b6002546101b6906001600160a01b031681565b6000546001600160a01b03166101b6565b61015b6102303660046110a4565b610848565b61015b6102433660046112ec565b6108ac565b6101e96102563660046110a4565b6108ca565b6101336102693660046110a4565b60016020526000908152604090205460ff1681565b61015b61028c36600461132e565b610969565b6101e961029f3660046113e8565b6109eb565b6101e96102b23660046110a4565b610a52565b60006001600160e01b031982167f6789e32c00000000000000000000000000000000000000000000000000000000148061031a57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b600061032d338484610574565b9392505050565b60025460009061031a90339084906001600160a01b0316610574565b600080610365876001600160a01b0316610ae7565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602082015290810182905290915060009060600160408051601f198184030181529082905280516020918201207f34d67199000000000000000000000000000000000000000000000000000000009183019190915260608a811b6bffffffffffffffffffffffff1990811660248501528a821b8116603885015289821b16604c84015282018790529150600090608001604051602081830303815290604052805190602001209050600061046b827f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b9050610479868b838a610b67565b60405183906001600160a01b038c16907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040516305ef2c7f60e41b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018590526001600160a01b038a811660448301528981166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a401600060405180830381600087803b15801561054e57600080fd5b505af1158015610562573d6000803e3d6000fd5b50949c9b505050505050505050505050565b6000836001600160a01b03811633148015906105a057503360009081526001602052604090205460ff16155b801561065257506040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301523360248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c590604401602060405180830381865afa15801561062c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106509190611416565b155b8015610664575061066281610c2d565b155b1561069b576040517fd7a2ae6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106af866001600160a01b0316610ae7565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602080830191909152818301849052825180830384018152606090920192839052815191012091925081906001600160a01b038916907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040516305ef2c7f60e41b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018390526001600160a01b0387811660448301528681166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a4015b600060405180830381600087803b1580156107d057600080fd5b505af11580156107e4573d6000803e3d6000fd5b50929998505050505050505050565b6107fb610cf1565b6108056000610d4b565b565b600080610815878787610574565b604051637737221360e01b81529091506001600160a01b038616906377372213906107b690849088908890600401611433565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e261087d6001600160a01b038416610ae7565b604080516020810193909352820152606001604051602081830303815290604052805190602001209050919050565b60025460009061032d90339081906001600160a01b03168686610807565b6108d2610cf1565b6001600160a01b038116610912576040517f7ea067a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517feae17a84d9eb83d8c8eb317f9e7d64857bc363fa51674d996c023f4340c577cf90600090a250565b6000806109798989898989610350565b604051637737221360e01b81529091506001600160a01b038816906377372213906109ac90849088908890600401611433565b600060405180830381600087803b1580156109c657600080fd5b505af11580156109da573d6000803e3d6000fd5b50929b9a5050505050505050505050565b6109f3610cf1565b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f4c97694570a07277810af7e5669ffd5f6a2d6b74b6e9a274b8b870fd5114cf87910160405180910390a25050565b610a5a610cf1565b6001600160a01b038116610adb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610ae481610d4b565b50565b600060285b8015610b5b57600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601090920491600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601083049250610aec565b50506028600020919050565b610b72838386610da8565b610ba8576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42811015610be2576040517f0819bdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bee42610e10611469565b811115610c27576040517f5e4989ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000816001600160a01b03163b600003610c4957506000919050565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610ca3575060408051601f3d908101601f19168201909252610ca09181019061148a565b60015b610ce0573d808015610cd1576040519150601f19603f3d011682016040523d82523d6000602084013e610cd6565b606091505b5060009392505050565b6001600160a01b0316331492915050565b6000546001600160a01b031633146108055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ad2565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000610db78585610e09565b90925090506000816004811115610dd057610dd06114a7565b148015610dee5750856001600160a01b0316826001600160a01b0316145b80610dff5750610dff868686610e4e565b9695505050505050565b6000808251604103610e3f5760208301516040840151606085015160001a610e3387828585610f68565b94509450505050610e47565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610e789291906114e1565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909416939093179092529051610ecb919061151b565b600060405180830381855afa9150503d8060008114610f06576040519150601f19603f3d011682016040523d82523d6000602084013e610f0b565b606091505b5091509150818015610f1f57506020815110155b8015610dff575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090610f5d9083016020908101908401611537565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610f9f5750600090506003611023565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610ff3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661101c57600060019250925050611023565b9150600090505b94509492505050565b60006020828403121561103e57600080fd5b81356001600160e01b03198116811461032d57600080fd5b6001600160a01b0381168114610ae457600080fd5b6000806040838503121561107e57600080fd5b823561108981611056565b9150602083013561109981611056565b809150509250929050565b6000602082840312156110b657600080fd5b813561032d81611056565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126110e857600080fd5b813567ffffffffffffffff80821115611103576111036110c1565b604051601f8301601f19908116603f0116810190828211818310171561112b5761112b6110c1565b8160405283815286602085880101111561114457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a0868803121561117c57600080fd5b853561118781611056565b9450602086013561119781611056565b935060408601356111a781611056565b925060608601359150608086013567ffffffffffffffff8111156111ca57600080fd5b6111d6888289016110d7565b9150509295509295909350565b6000806000606084860312156111f857600080fd5b833561120381611056565b9250602084013561121381611056565b9150604084013561122381611056565b809150509250925092565b60008083601f84011261124057600080fd5b50813567ffffffffffffffff81111561125857600080fd5b602083019150836020828501011115610e4757600080fd5b60008060008060006080868803121561128857600080fd5b853561129381611056565b945060208601356112a381611056565b935060408601356112b381611056565b9250606086013567ffffffffffffffff8111156112cf57600080fd5b6112db8882890161122e565b969995985093965092949392505050565b600080602083850312156112ff57600080fd5b823567ffffffffffffffff81111561131657600080fd5b6113228582860161122e565b90969095509350505050565b600080600080600080600060c0888a03121561134957600080fd5b873561135481611056565b9650602088013561136481611056565b9550604088013561137481611056565b945060608801359350608088013567ffffffffffffffff8082111561139857600080fd5b6113a48b838c016110d7565b945060a08a01359150808211156113ba57600080fd5b506113c78a828b0161122e565b989b979a50959850939692959293505050565b8015158114610ae457600080fd5b600080604083850312156113fb57600080fd5b823561140681611056565b91506020830135611099816113da565b60006020828403121561142857600080fd5b815161032d816113da565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b8082018082111561031a57634e487b7160e01b600052601160045260246000fd5b60006020828403121561149c57600080fd5b815161032d81611056565b634e487b7160e01b600052602160045260246000fd5b60005b838110156114d85781810151838201526020016114c0565b50506000910152565b82815260406020820152600082518060408401526115068160608501602087016114bd565b601f01601f1916919091016060019392505050565b6000825161152d8184602087016114bd565b9190910192915050565b60006020828403121561154957600080fd5b505191905056fea2646970667358221220aa39c2af36a6fb912271f06a3290824779a31f48df3ec8792458ac5bd9dfba9b64736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061011b5760003560e01c8063828eab0e116100b2578063c66485b211610081578063e0801e9a11610066578063e0801e9a1461027e578063e0dba60f14610291578063f2fde38b146102a457600080fd5b8063c66485b214610248578063da8c229e1461025b57600080fd5b8063828eab0e146101fe5780638da5cb5b14610211578063bffbe61c14610222578063c47f00271461023557600080fd5b80633f15457f116100ee5780633f15457f1461018f57806365669631146101ce578063715018a6146101e15780637a806d6b146101eb57600080fd5b806301ffc9a7146101205780630f5a5466146101485780631e83409a1461016957806334d671991461017c575b600080fd5b61013361012e36600461102c565b6102b7565b60405190151581526020015b60405180910390f35b61015b61015636600461106b565b610320565b60405190815260200161013f565b61015b6101773660046110a4565b610334565b61015b61018a366004611164565b610350565b6101b67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161013f565b61015b6101dc3660046111e3565b610574565b6101e96107f3565b005b61015b6101f9366004611270565b610807565b6002546101b6906001600160a01b031681565b6000546001600160a01b03166101b6565b61015b6102303660046110a4565b610848565b61015b6102433660046112ec565b6108ac565b6101e96102563660046110a4565b6108ca565b6101336102693660046110a4565b60016020526000908152604090205460ff1681565b61015b61028c36600461132e565b610969565b6101e961029f3660046113e8565b6109eb565b6101e96102b23660046110a4565b610a52565b60006001600160e01b031982167f6789e32c00000000000000000000000000000000000000000000000000000000148061031a57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b600061032d338484610574565b9392505050565b60025460009061031a90339084906001600160a01b0316610574565b600080610365876001600160a01b0316610ae7565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602082015290810182905290915060009060600160408051601f198184030181529082905280516020918201207f34d67199000000000000000000000000000000000000000000000000000000009183019190915260608a811b6bffffffffffffffffffffffff1990811660248501528a821b8116603885015289821b16604c84015282018790529150600090608001604051602081830303815290604052805190602001209050600061046b827f19457468657265756d205369676e6564204d6573736167653a0a3332000000006000908152601c91909152603c902090565b9050610479868b838a610b67565b60405183906001600160a01b038c16907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040516305ef2c7f60e41b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018590526001600160a01b038a811660448301528981166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a401600060405180830381600087803b15801561054e57600080fd5b505af1158015610562573d6000803e3d6000fd5b50949c9b505050505050505050505050565b6000836001600160a01b03811633148015906105a057503360009081526001602052604090205460ff16155b801561065257506040517fe985e9c50000000000000000000000000000000000000000000000000000000081526001600160a01b0382811660048301523360248301527f0000000000000000000000000000000000000000000000000000000000000000169063e985e9c590604401602060405180830381865afa15801561062c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106509190611416565b155b8015610664575061066281610c2d565b155b1561069b576040517fd7a2ae6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006106af866001600160a01b0316610ae7565b604080517f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e2602080830191909152818301849052825180830384018152606090920192839052815191012091925081906001600160a01b038916907f6ada868dd3058cf77a48a74489fd7963688e5464b2b0fa957ace976243270e9290600090a36040516305ef2c7f60e41b81527f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e26004820152602481018390526001600160a01b0387811660448301528681166064830152600060848301527f00000000000000000000000000000000000000000000000000000000000000001690635ef2c7f09060a4015b600060405180830381600087803b1580156107d057600080fd5b505af11580156107e4573d6000803e3d6000fd5b50929998505050505050505050565b6107fb610cf1565b6108056000610d4b565b565b600080610815878787610574565b604051637737221360e01b81529091506001600160a01b038616906377372213906107b690849088908890600401611433565b60007f91d1777781884d03a6757a803996e38de2a42967fb37eeaca72729271025a9e261087d6001600160a01b038416610ae7565b604080516020810193909352820152606001604051602081830303815290604052805190602001209050919050565b60025460009061032d90339081906001600160a01b03168686610807565b6108d2610cf1565b6001600160a01b038116610912576040517f7ea067a100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517feae17a84d9eb83d8c8eb317f9e7d64857bc363fa51674d996c023f4340c577cf90600090a250565b6000806109798989898989610350565b604051637737221360e01b81529091506001600160a01b038816906377372213906109ac90849088908890600401611433565b600060405180830381600087803b1580156109c657600080fd5b505af11580156109da573d6000803e3d6000fd5b50929b9a5050505050505050505050565b6109f3610cf1565b6001600160a01b038216600081815260016020908152604091829020805460ff191685151590811790915591519182527f4c97694570a07277810af7e5669ffd5f6a2d6b74b6e9a274b8b870fd5114cf87910160405180910390a25050565b610a5a610cf1565b6001600160a01b038116610adb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610ae481610d4b565b50565b600060285b8015610b5b57600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601090920491600019017f3031323334353637383961626364656600000000000000000000000000000000600f84161a8153601083049250610aec565b50506028600020919050565b610b72838386610da8565b610ba8576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42811015610be2576040517f0819bdcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bee42610e10611469565b811115610c27576040517f5e4989ee00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000816001600160a01b03163b600003610c4957506000919050565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015610ca3575060408051601f3d908101601f19168201909252610ca09181019061148a565b60015b610ce0573d808015610cd1576040519150601f19603f3d011682016040523d82523d6000602084013e610cd6565b606091505b5060009392505050565b6001600160a01b0316331492915050565b6000546001600160a01b031633146108055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ad2565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000806000610db78585610e09565b90925090506000816004811115610dd057610dd06114a7565b148015610dee5750856001600160a01b0316826001600160a01b0316145b80610dff5750610dff868686610e4e565b9695505050505050565b6000808251604103610e3f5760208301516040840151606085015160001a610e3387828585610f68565b94509450505050610e47565b506000905060025b9250929050565b6000806000856001600160a01b0316631626ba7e60e01b8686604051602401610e789291906114e1565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909416939093179092529051610ecb919061151b565b600060405180830381855afa9150503d8060008114610f06576040519150601f19603f3d011682016040523d82523d6000602084013e610f0b565b606091505b5091509150818015610f1f57506020815110155b8015610dff575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090610f5d9083016020908101908401611537565b149695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115610f9f5750600090506003611023565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015610ff3573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661101c57600060019250925050611023565b9150600090505b94509492505050565b60006020828403121561103e57600080fd5b81356001600160e01b03198116811461032d57600080fd5b6001600160a01b0381168114610ae457600080fd5b6000806040838503121561107e57600080fd5b823561108981611056565b9150602083013561109981611056565b809150509250929050565b6000602082840312156110b657600080fd5b813561032d81611056565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126110e857600080fd5b813567ffffffffffffffff80821115611103576111036110c1565b604051601f8301601f19908116603f0116810190828211818310171561112b5761112b6110c1565b8160405283815286602085880101111561114457600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600080600060a0868803121561117c57600080fd5b853561118781611056565b9450602086013561119781611056565b935060408601356111a781611056565b925060608601359150608086013567ffffffffffffffff8111156111ca57600080fd5b6111d6888289016110d7565b9150509295509295909350565b6000806000606084860312156111f857600080fd5b833561120381611056565b9250602084013561121381611056565b9150604084013561122381611056565b809150509250925092565b60008083601f84011261124057600080fd5b50813567ffffffffffffffff81111561125857600080fd5b602083019150836020828501011115610e4757600080fd5b60008060008060006080868803121561128857600080fd5b853561129381611056565b945060208601356112a381611056565b935060408601356112b381611056565b9250606086013567ffffffffffffffff8111156112cf57600080fd5b6112db8882890161122e565b969995985093965092949392505050565b600080602083850312156112ff57600080fd5b823567ffffffffffffffff81111561131657600080fd5b6113228582860161122e565b90969095509350505050565b600080600080600080600060c0888a03121561134957600080fd5b873561135481611056565b9650602088013561136481611056565b9550604088013561137481611056565b945060608801359350608088013567ffffffffffffffff8082111561139857600080fd5b6113a48b838c016110d7565b945060a08a01359150808211156113ba57600080fd5b506113c78a828b0161122e565b989b979a50959850939692959293505050565b8015158114610ae457600080fd5b600080604083850312156113fb57600080fd5b823561140681611056565b91506020830135611099816113da565b60006020828403121561142857600080fd5b815161032d816113da565b83815260406020820152816040820152818360608301376000818301606090810191909152601f909201601f1916010192915050565b8082018082111561031a57634e487b7160e01b600052601160045260246000fd5b60006020828403121561149c57600080fd5b815161032d81611056565b634e487b7160e01b600052602160045260246000fd5b60005b838110156114d85781810151838201526020016114c0565b50506000910152565b82815260406020820152600082518060408401526115068160608501602087016114bd565b601f01601f1916919091016060019392505050565b6000825161152d8184602087016114bd565b9190910192915050565b60006020828403121561154957600080fd5b505191905056fea2646970667358221220aa39c2af36a6fb912271f06a3290824779a31f48df3ec8792458ac5bd9dfba9b64736f6c63430008110033", "devdoc": { "kind": "dev", "methods": { "claim(address)": { - "details": "Transfers ownership of the reverse ENS record associated with the calling account.", "params": { "owner": "The address to set as the owner of the reverse record in ENS." }, "returns": { - "_0": "The ENS node hash of the reverse record." + "_0": "The ENS node hash of the reverse record" } }, "claimForAddr(address,address,address)": { - "details": "Transfers ownership of the reverse ENS record associated with the calling account.", "params": { - "addr": "The reverse record to set", - "owner": "The address to set as the owner of the reverse record in ENS.", + "addr": "The address to claim the reverse record for", + "owner": "The address to set as the owner of the reverse record", "resolver": "The resolver of the reverse node" }, "returns": { - "_0": "The ENS node hash of the reverse record." + "_0": "The ENS node hash of the reverse record" + } + }, + "claimForAddrWithSignature(address,address,address,uint256,bytes)": { + "params": { + "addr": "The address to claim the reverse record for", + "owner": "The address to set as the owner of the reverse record", + "resolver": "The resolver of the reverse node", + "signature": "The signature to authorise the claim", + "signatureExpiry": "The expiry of the signature" + }, + "returns": { + "_0": "The ENS node hash of the reverse record" } }, "claimWithResolver(address,address)": { - "details": "Transfers ownership of the reverse ENS record associated with the calling account.", "params": { - "owner": "The address to set as the owner of the reverse record in ENS.", - "resolver": "The address of the resolver to set; 0 to leave unchanged." + "owner": "The address to set as the owner of the reverse record", + "resolver": "The resolver of the reverse node" }, "returns": { - "_0": "The ENS node hash of the reverse record." + "_0": "The ENS node hash of the reverse record" } }, "constructor": { - "details": "Constructor", "params": { - "ensAddr": "The address of the ENS registry." + "ensAddr": "The address of the ENS registry" } }, "node(address)": { - "details": "Returns the node hash for a given account's reverse records.", "params": { - "addr": "The address to hash" + "addr": "The address to get the reverse node hash for" }, "returns": { - "_0": "The ENS node hash." + "_0": "The ENS node hash" } }, "owner()": { @@ -429,42 +604,140 @@ "renounceOwnership()": { "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." }, + "setDefaultResolver(address)": { + "params": { + "resolver": "The resolver to set" + } + }, "setName(string)": { - "details": "Sets the `name()` record for the reverse ENS record associated with the calling account. First updates the resolver to the default reverse resolver if necessary.", "params": { - "name": "The name to set for this address." + "name": "The name to set for the calling account" }, "returns": { - "_0": "The ENS node hash of the reverse record." + "_0": "The ENS node hash of the reverse record" } }, "setNameForAddr(address,address,address,string)": { - "details": "Sets the `name()` record for the reverse ENS record associated with the account provided. Updates the resolver to a designated resolver Only callable by controllers and authorised users", "params": { "addr": "The reverse record to set", - "name": "The name to set for this address.", + "name": "The name to set for the provided address", "owner": "The owner of the reverse node", "resolver": "The resolver of the reverse node" }, "returns": { - "_0": "The ENS node hash of the reverse record." + "_0": "The ENS node hash of the reverse record" } }, + "setNameForAddrWithSignature(address,address,address,uint256,bytes,string)": { + "params": { + "addr": "The reverse record to set", + "name": "The name to set for the provided address", + "owner": "The owner of the reverse node", + "resolver": "The resolver of the reverse node", + "signature": "The signature to authorise the claim", + "signatureExpiry": "The expiry of the signature" + }, + "returns": { + "_0": "The ENS node hash of the reverse record" + } + }, + "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." } }, + "stateVariables": { + "ADDR_REVERSE_NODE": { + "details": "`namehash('addr.reverse')`" + } + }, + "title": "ENS Reverse Registrar", "version": 1 }, "userdoc": { + "errors": { + "InvalidSignature()": [ + { + "notice": "The signature is invalid" + } + ], + "ResolverAddressZero()": [ + { + "notice": "Thrown when the resolver address is zero" + } + ], + "SignatureExpired()": [ + { + "notice": "The signature has expired" + } + ], + "SignatureExpiryTooHigh()": [ + { + "notice": "The signature expiry is too high" + } + ], + "Unauthorised()": [ + { + "notice": "Thrown when the caller is not authorised to perform the action" + } + ] + }, + "events": { + "DefaultResolverChanged(address)": { + "notice": "Emitted when the default resolver is changed." + }, + "ReverseClaimed(address,bytes32)": { + "notice": "Emitted when a reverse record is claimed." + } + }, "kind": "user", - "methods": {}, + "methods": { + "claim(address)": { + "notice": "Transfers ownership of the reverse ENS record associated with the calling account." + }, + "claimForAddr(address,address,address)": { + "notice": "Transfers ownership of the reverse ENS record associated with the addr provided account." + }, + "claimForAddrWithSignature(address,address,address,uint256,bytes)": { + "notice": "Transfers ownership of the reverse ENS record associated with the addr provided account using a signature to authorise." + }, + "claimWithResolver(address,address)": { + "notice": "Transfers ownership of the reverse ENS record associated with the calling account." + }, + "constructor": { + "notice": "Sets the ENS registry and claims `addr.reverse`" + }, + "defaultResolver()": { + "notice": "The default resolver" + }, + "ens()": { + "notice": "The ENS registry" + }, + "node(address)": { + "notice": "Returns the ENS node hash for the reverse record associated with the addr provided account." + }, + "setDefaultResolver(address)": { + "notice": "Sets the default resolver" + }, + "setName(string)": { + "notice": "Sets the `name()` record for the reverse ENS record associated with the calling account, and updates the resolver to the default reverse resolver." + }, + "setNameForAddr(address,address,address,string)": { + "notice": "Sets the `name()` record for the reverse ENS record associated with the addr provided account, and updates the resolver to the resolver provided." + }, + "setNameForAddrWithSignature(address,address,address,uint256,bytes,string)": { + "notice": "Sets the `name()` record for the reverse ENS record associated with the addr provided account using a signature to authorise, and updates the resolver to the resolver provided." + } + }, + "notice": "The registrar for reverse records on ENS", "version": 1 }, "storageLayout": { "storage": [ { - "astId": 444, + "astId": 428, "contract": "contracts/reverseRegistrar/ReverseRegistrar.sol:ReverseRegistrar", "label": "_owner", "offset": 0, @@ -472,7 +745,7 @@ "type": "t_address" }, { - "astId": 18581, + "astId": 15579, "contract": "contracts/reverseRegistrar/ReverseRegistrar.sol:ReverseRegistrar", "label": "controllers", "offset": 0, @@ -480,12 +753,12 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 18253, + "astId": 14833, "contract": "contracts/reverseRegistrar/ReverseRegistrar.sol:ReverseRegistrar", "label": "defaultResolver", "offset": 0, "slot": "2", - "type": "t_contract(NameResolver)18235" + "type": "t_contract(INameSetterResolver)14803" } ], "types": { @@ -499,9 +772,9 @@ "label": "bool", "numberOfBytes": "1" }, - "t_contract(NameResolver)18235": { + "t_contract(INameSetterResolver)14803": { "encoding": "inplace", - "label": "contract NameResolver", + "label": "contract INameSetterResolver", "numberOfBytes": "20" }, "t_mapping(t_address,t_bool)": { diff --git a/deployments/holesky/solcInputs/e27011e9521d1f56963a5ba6ba5278b4.json b/deployments/holesky/solcInputs/e27011e9521d1f56963a5ba6ba5278b4.json new file mode 100644 index 00000000..8edb02e3 --- /dev/null +++ b/deployments/holesky/solcInputs/e27011e9521d1f56963a5ba6ba5278b4.json @@ -0,0 +1,350 @@ +{ + "language": "Solidity", + "sources": { + "@ensdomains/buffer/contracts/Buffer.sol": { + "content": "// SPDX-License-Identifier: BSD-2-Clause\npragma solidity ^0.8.4;\n\n/**\n* @dev A library for working with mutable byte buffers in Solidity.\n*\n* Byte buffers are mutable and expandable, and provide a variety of primitives\n* for appending to them. At any time you can fetch a bytes object containing the\n* current contents of the buffer. The bytes object should not be stored between\n* operations, as it may change due to resizing of the buffer.\n*/\nlibrary Buffer {\n /**\n * @dev Represents a mutable buffer. Buffers have a current value (buf) and\n * a capacity. The capacity may be longer than the current value, in\n * which case it can be extended without the need to allocate more memory.\n */\n struct buffer {\n bytes buf;\n uint capacity;\n }\n\n /**\n * @dev Initializes a buffer with an initial capacity.\n * @param buf The buffer to initialize.\n * @param capacity The number of bytes of space to allocate the buffer.\n * @return The buffer, for chaining.\n */\n function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {\n if (capacity % 32 != 0) {\n capacity += 32 - (capacity % 32);\n }\n // Allocate space for the buffer data\n buf.capacity = capacity;\n assembly {\n let ptr := mload(0x40)\n mstore(buf, ptr)\n mstore(ptr, 0)\n let fpm := add(32, add(ptr, capacity))\n if lt(fpm, ptr) {\n revert(0, 0)\n }\n mstore(0x40, fpm)\n }\n return buf;\n }\n\n /**\n * @dev Initializes a new buffer from an existing bytes object.\n * Changes to the buffer may mutate the original value.\n * @param b The bytes object to initialize the buffer with.\n * @return A new buffer.\n */\n function fromBytes(bytes memory b) internal pure returns(buffer memory) {\n buffer memory buf;\n buf.buf = b;\n buf.capacity = b.length;\n return buf;\n }\n\n function resize(buffer memory buf, uint capacity) private pure {\n bytes memory oldbuf = buf.buf;\n init(buf, capacity);\n append(buf, oldbuf);\n }\n\n /**\n * @dev Sets buffer length to 0.\n * @param buf The buffer to truncate.\n * @return The original buffer, for chaining..\n */\n function truncate(buffer memory buf) internal pure returns (buffer memory) {\n assembly {\n let bufptr := mload(buf)\n mstore(bufptr, 0)\n }\n return buf;\n }\n\n /**\n * @dev Appends len bytes of a byte string to a buffer. Resizes if doing so would exceed\n * the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @param len The number of bytes to copy.\n * @return The original buffer, for chaining.\n */\n function append(buffer memory buf, bytes memory data, uint len) internal pure returns(buffer memory) {\n require(len <= data.length);\n\n uint off = buf.buf.length;\n uint newCapacity = off + len;\n if (newCapacity > buf.capacity) {\n resize(buf, newCapacity * 2);\n }\n\n uint dest;\n uint src;\n assembly {\n // Memory address of the buffer data\n let bufptr := mload(buf)\n // Length of existing buffer data\n let buflen := mload(bufptr)\n // Start address = buffer address + offset + sizeof(buffer length)\n dest := add(add(bufptr, 32), off)\n // Update buffer length if we're extending it\n if gt(newCapacity, buflen) {\n mstore(bufptr, newCapacity)\n }\n src := add(data, 32)\n }\n\n // Copy word-length chunks while possible\n for (; len >= 32; len -= 32) {\n assembly {\n mstore(dest, mload(src))\n }\n dest += 32;\n src += 32;\n }\n\n // Copy remaining bytes\n unchecked {\n uint mask = (256 ** (32 - len)) - 1;\n assembly {\n let srcpart := and(mload(src), not(mask))\n let destpart := and(mload(dest), mask)\n mstore(dest, or(destpart, srcpart))\n }\n }\n\n return buf;\n }\n\n /**\n * @dev Appends a byte string to a buffer. Resizes if doing so would exceed\n * the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @return The original buffer, for chaining.\n */\n function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {\n return append(buf, data, data.length);\n }\n\n /**\n * @dev Appends a byte to the buffer. Resizes if doing so would exceed the\n * capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @return The original buffer, for chaining.\n */\n function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {\n uint off = buf.buf.length;\n uint offPlusOne = off + 1;\n if (off >= buf.capacity) {\n resize(buf, offPlusOne * 2);\n }\n\n assembly {\n // Memory address of the buffer data\n let bufptr := mload(buf)\n // Address = buffer address + sizeof(buffer length) + off\n let dest := add(add(bufptr, off), 32)\n mstore8(dest, data)\n // Update buffer length if we extended it\n if gt(offPlusOne, mload(bufptr)) {\n mstore(bufptr, offPlusOne)\n }\n }\n\n return buf;\n }\n\n /**\n * @dev Appends len bytes of bytes32 to a buffer. Resizes if doing so would\n * exceed the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @param len The number of bytes to write (left-aligned).\n * @return The original buffer, for chaining.\n */\n function append(buffer memory buf, bytes32 data, uint len) private pure returns(buffer memory) {\n uint off = buf.buf.length;\n uint newCapacity = len + off;\n if (newCapacity > buf.capacity) {\n resize(buf, newCapacity * 2);\n }\n\n unchecked {\n uint mask = (256 ** len) - 1;\n // Right-align data\n data = data >> (8 * (32 - len));\n assembly {\n // Memory address of the buffer data\n let bufptr := mload(buf)\n // Address = buffer address + sizeof(buffer length) + newCapacity\n let dest := add(bufptr, newCapacity)\n mstore(dest, or(and(mload(dest), not(mask)), data))\n // Update buffer length if we extended it\n if gt(newCapacity, mload(bufptr)) {\n mstore(bufptr, newCapacity)\n }\n }\n }\n return buf;\n }\n\n /**\n * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed\n * the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @return The original buffer, for chhaining.\n */\n function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {\n return append(buf, bytes32(data), 20);\n }\n\n /**\n * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed\n * the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @return The original buffer, for chaining.\n */\n function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {\n return append(buf, data, 32);\n }\n\n /**\n * @dev Appends a byte to the end of the buffer. Resizes if doing so would\n * exceed the capacity of the buffer.\n * @param buf The buffer to append to.\n * @param data The data to append.\n * @param len The number of bytes to write (right-aligned).\n * @return The original buffer.\n */\n function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {\n uint off = buf.buf.length;\n uint newCapacity = len + off;\n if (newCapacity > buf.capacity) {\n resize(buf, newCapacity * 2);\n }\n\n uint mask = (256 ** len) - 1;\n assembly {\n // Memory address of the buffer data\n let bufptr := mload(buf)\n // Address = buffer address + sizeof(buffer length) + newCapacity\n let dest := add(bufptr, newCapacity)\n mstore(dest, or(and(mload(dest), not(mask)), data))\n // Update buffer length if we extended it\n if gt(newCapacity, mload(bufptr)) {\n mstore(bufptr, newCapacity)\n }\n }\n return buf;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby disabling any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155.sol\";\n\n/**\n * @dev Interface of the optional ERC1155MetadataExtension interface, as defined\n * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155MetadataURI is IERC1155 {\n /**\n * @dev Returns the URI for token type `id`.\n *\n * If the `\\{id\\}` substring is present in the URI, it must be replaced by\n * clients with the actual token type ID.\n */\n function uri(uint256 id) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC1155 compliant contract, as defined in the\n * https://eips.ethereum.org/EIPS/eip-1155[EIP].\n *\n * _Available since v3.1._\n */\ninterface IERC1155 is IERC165 {\n /**\n * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.\n */\n event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);\n\n /**\n * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all\n * transfers.\n */\n event TransferBatch(\n address indexed operator,\n address indexed from,\n address indexed to,\n uint256[] ids,\n uint256[] values\n );\n\n /**\n * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to\n * `approved`.\n */\n event ApprovalForAll(address indexed account, address indexed operator, bool approved);\n\n /**\n * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.\n *\n * If an {URI} event was emitted for `id`, the standard\n * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value\n * returned by {IERC1155MetadataURI-uri}.\n */\n event URI(string value, uint256 indexed id);\n\n /**\n * @dev Returns the amount of tokens of token type `id` owned by `account`.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function balanceOf(address account, uint256 id) external view returns (uint256);\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.\n *\n * Requirements:\n *\n * - `accounts` and `ids` must have the same length.\n */\n function balanceOfBatch(\n address[] calldata accounts,\n uint256[] calldata ids\n ) external view returns (uint256[] memory);\n\n /**\n * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,\n *\n * Emits an {ApprovalForAll} event.\n *\n * Requirements:\n *\n * - `operator` cannot be the caller.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.\n *\n * See {setApprovalForAll}.\n */\n function isApprovedForAll(address account, address operator) external view returns (bool);\n\n /**\n * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.\n *\n * Emits a {TransferSingle} event.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.\n * - `from` must have a balance of tokens of type `id` of at least `amount`.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the\n * acceptance magic value.\n */\n function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;\n\n /**\n * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.\n *\n * Emits a {TransferBatch} event.\n *\n * Requirements:\n *\n * - `ids` and `amounts` must have the same length.\n * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the\n * acceptance magic value.\n */\n function safeBatchTransferFrom(\n address from,\n address to,\n uint256[] calldata ids,\n uint256[] calldata amounts,\n bytes calldata data\n ) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the default value returned by this function, unless\n * it's overridden.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/ERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC721.sol\";\nimport \"./IERC721Receiver.sol\";\nimport \"./extensions/IERC721Metadata.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/Context.sol\";\nimport \"../../utils/Strings.sol\";\nimport \"../../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\n * {ERC721Enumerable}.\n */\ncontract ERC721 is Context, ERC165, IERC721, IERC721Metadata {\n using Address for address;\n using Strings for uint256;\n\n // Token name\n string private _name;\n\n // Token symbol\n string private _symbol;\n\n // Mapping from token ID to owner address\n mapping(uint256 => address) private _owners;\n\n // Mapping owner address to token count\n mapping(address => uint256) private _balances;\n\n // Mapping from token ID to approved address\n mapping(uint256 => address) private _tokenApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n /**\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return\n interfaceId == type(IERC721).interfaceId ||\n interfaceId == type(IERC721Metadata).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev See {IERC721-balanceOf}.\n */\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ERC721: address zero is not a valid owner\");\n return _balances[owner];\n }\n\n /**\n * @dev See {IERC721-ownerOf}.\n */\n function ownerOf(uint256 tokenId) public view virtual override returns (address) {\n address owner = _ownerOf(tokenId);\n require(owner != address(0), \"ERC721: invalid token ID\");\n return owner;\n }\n\n /**\n * @dev See {IERC721Metadata-name}.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev See {IERC721Metadata-symbol}.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev See {IERC721Metadata-tokenURI}.\n */\n function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {\n _requireMinted(tokenId);\n\n string memory baseURI = _baseURI();\n return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : \"\";\n }\n\n /**\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\n * by default, can be overridden in child contracts.\n */\n function _baseURI() internal view virtual returns (string memory) {\n return \"\";\n }\n\n /**\n * @dev See {IERC721-approve}.\n */\n function approve(address to, uint256 tokenId) public virtual override {\n address owner = ERC721.ownerOf(tokenId);\n require(to != owner, \"ERC721: approval to current owner\");\n\n require(\n _msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n \"ERC721: approve caller is not token owner or approved for all\"\n );\n\n _approve(to, tokenId);\n }\n\n /**\n * @dev See {IERC721-getApproved}.\n */\n function getApproved(uint256 tokenId) public view virtual override returns (address) {\n _requireMinted(tokenId);\n\n return _tokenApprovals[tokenId];\n }\n\n /**\n * @dev See {IERC721-setApprovalForAll}.\n */\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _setApprovalForAll(_msgSender(), operator, approved);\n }\n\n /**\n * @dev See {IERC721-isApprovedForAll}.\n */\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _operatorApprovals[owner][operator];\n }\n\n /**\n * @dev See {IERC721-transferFrom}.\n */\n function transferFrom(address from, address to, uint256 tokenId) public virtual override {\n //solhint-disable-next-line max-line-length\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n\n _transfer(from, to, tokenId);\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {\n safeTransferFrom(from, to, tokenId, \"\");\n }\n\n /**\n * @dev See {IERC721-safeTransferFrom}.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {\n require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: caller is not token owner or approved\");\n _safeTransfer(from, to, tokenId, data);\n }\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\n *\n * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.\n * implement alternative mechanisms to perform token transfer, such as signature-based.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\n _transfer(from, to, tokenId);\n require(_checkOnERC721Received(from, to, tokenId, data), \"ERC721: transfer to non ERC721Receiver implementer\");\n }\n\n /**\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\n */\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\n return _owners[tokenId];\n }\n\n /**\n * @dev Returns whether `tokenId` exists.\n *\n * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.\n *\n * Tokens start existing when they are minted (`_mint`),\n * and stop existing when they are burned (`_burn`).\n */\n function _exists(uint256 tokenId) internal view virtual returns (bool) {\n return _ownerOf(tokenId) != address(0);\n }\n\n /**\n * @dev Returns whether `spender` is allowed to manage `tokenId`.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {\n address owner = ERC721.ownerOf(tokenId);\n return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);\n }\n\n /**\n * @dev Safely mints `tokenId` and transfers it to `to`.\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function _safeMint(address to, uint256 tokenId) internal virtual {\n _safeMint(to, tokenId, \"\");\n }\n\n /**\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\n */\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\n _mint(to, tokenId);\n require(\n _checkOnERC721Received(address(0), to, tokenId, data),\n \"ERC721: transfer to non ERC721Receiver implementer\"\n );\n }\n\n /**\n * @dev Mints `tokenId` and transfers it to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\n *\n * Requirements:\n *\n * - `tokenId` must not exist.\n * - `to` cannot be the zero address.\n *\n * Emits a {Transfer} event.\n */\n function _mint(address to, uint256 tokenId) internal virtual {\n require(to != address(0), \"ERC721: mint to the zero address\");\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n _beforeTokenTransfer(address(0), to, tokenId, 1);\n\n // Check that tokenId was not minted by `_beforeTokenTransfer` hook\n require(!_exists(tokenId), \"ERC721: token already minted\");\n\n unchecked {\n // Will not overflow unless all 2**256 token ids are minted to the same owner.\n // Given that tokens are minted one by one, it is impossible in practice that\n // this ever happens. Might change if we allow batch minting.\n // The ERC fails to describe this case.\n _balances[to] += 1;\n }\n\n _owners[tokenId] = to;\n\n emit Transfer(address(0), to, tokenId);\n\n _afterTokenTransfer(address(0), to, tokenId, 1);\n }\n\n /**\n * @dev Destroys `tokenId`.\n * The approval is cleared when the token is burned.\n * This is an internal function that does not check if the sender is authorized to operate on the token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n *\n * Emits a {Transfer} event.\n */\n function _burn(uint256 tokenId) internal virtual {\n address owner = ERC721.ownerOf(tokenId);\n\n _beforeTokenTransfer(owner, address(0), tokenId, 1);\n\n // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook\n owner = ERC721.ownerOf(tokenId);\n\n // Clear approvals\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // Cannot overflow, as that would require more tokens to be burned/transferred\n // out than the owner initially received through minting and transferring in.\n _balances[owner] -= 1;\n }\n delete _owners[tokenId];\n\n emit Transfer(owner, address(0), tokenId);\n\n _afterTokenTransfer(owner, address(0), tokenId, 1);\n }\n\n /**\n * @dev Transfers `tokenId` from `from` to `to`.\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n *\n * Emits a {Transfer} event.\n */\n function _transfer(address from, address to, uint256 tokenId) internal virtual {\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n require(to != address(0), \"ERC721: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, tokenId, 1);\n\n // Check that tokenId was not transferred by `_beforeTokenTransfer` hook\n require(ERC721.ownerOf(tokenId) == from, \"ERC721: transfer from incorrect owner\");\n\n // Clear approvals from the previous owner\n delete _tokenApprovals[tokenId];\n\n unchecked {\n // `_balances[from]` cannot overflow for the same reason as described in `_burn`:\n // `from`'s balance is the number of token held, which is at least one before the current\n // transfer.\n // `_balances[to]` could overflow in the conditions described in `_mint`. That would require\n // all 2**256 token ids to be minted, which in practice is impossible.\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[tokenId] = to;\n\n emit Transfer(from, to, tokenId);\n\n _afterTokenTransfer(from, to, tokenId, 1);\n }\n\n /**\n * @dev Approve `to` to operate on `tokenId`\n *\n * Emits an {Approval} event.\n */\n function _approve(address to, uint256 tokenId) internal virtual {\n _tokenApprovals[tokenId] = to;\n emit Approval(ERC721.ownerOf(tokenId), to, tokenId);\n }\n\n /**\n * @dev Approve `operator` to operate on all of `owner` tokens\n *\n * Emits an {ApprovalForAll} event.\n */\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\n require(owner != operator, \"ERC721: approve to caller\");\n _operatorApprovals[owner][operator] = approved;\n emit ApprovalForAll(owner, operator, approved);\n }\n\n /**\n * @dev Reverts if the `tokenId` has not been minted yet.\n */\n function _requireMinted(uint256 tokenId) internal view virtual {\n require(_exists(tokenId), \"ERC721: invalid token ID\");\n }\n\n /**\n * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n * The call is not executed if the target address is not a contract.\n *\n * @param from address representing the previous owner of the given token ID\n * @param to target address that will receive the tokens\n * @param tokenId uint256 ID of the token to be transferred\n * @param data bytes optional data to send along with the call\n * @return bool whether the call correctly returned the expected magic value\n */\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 tokenId,\n bytes memory data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\n return retval == IERC721Receiver.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert(\"ERC721: transfer to non ERC721Receiver implementer\");\n } else {\n /// @solidity memory-safe-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /**\n * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.\n * - When `from` is zero, the tokens will be minted for `to`.\n * - When `to` is zero, ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is\n * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.\n *\n * Calling conditions:\n *\n * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.\n * - When `from` is zero, the tokens were minted for `to`.\n * - When `to` is zero, ``from``'s tokens were burned.\n * - `from` and `to` are never both zero.\n * - `batchSize` is non-zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}\n\n /**\n * @dev Unsafe write access to the balances, used by extensions that \"mint\" tokens using an {ownerOf} override.\n *\n * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant\n * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such\n * that `ownerOf(tokenId)` is `a`.\n */\n // solhint-disable-next-line func-name-mixedcase\n function __unsafe_increaseBalance(address account, uint256 amount) internal {\n _balances[account] += amount;\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 tokenId) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@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/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n mstore(0x1c, hash)\n message := keccak256(0x00, 0x3c)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40)\n mstore(ptr, \"\\x19\\x01\")\n mstore(add(ptr, 0x02), domainSeparator)\n mstore(add(ptr, 0x22), structHash)\n data := keccak256(ptr, 0x42)\n }\n }\n\n /**\n * @dev Returns an Ethereum Signed Data with intended validator, created from a\n * `validator` and `data` according to the version 0 of EIP-191.\n *\n * See {recover}.\n */\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/SignatureChecker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\nimport \"../../interfaces/IERC1271.sol\";\n\n/**\n * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like\n * Argent and Gnosis Safe.\n *\n * _Available since v4.1._\n */\nlibrary SignatureChecker {\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\n * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) internal view returns (bool) {\n (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);\n return\n (error == ECDSA.RecoverError.NoError && recovered == signer) ||\n isValidERC1271SignatureNow(signer, hash, signature);\n }\n\n /**\n * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\n * against the signer smart contract using ERC1271.\n *\n * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\n * change through time. It could return true at block N and false at block N+1 (or the opposite).\n */\n function isValidERC1271SignatureNow(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) internal view returns (bool) {\n (bool success, bytes memory result) = signer.staticcall(\n abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)\n );\n return (success &&\n result.length >= 32 &&\n abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\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" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "clones-with-immutable-args/src/Clone.sol": { + "content": "// SPDX-License-Identifier: BSD\npragma solidity ^0.8.4;\n\n/// @title Clone\n/// @author zefram.eth\n/// @notice Provides helper functions for reading immutable args from calldata\ncontract Clone {\n /// @notice Reads an immutable arg with type address\n /// @param argOffset The offset of the arg in the packed data\n /// @return arg The arg value\n function _getArgAddress(uint256 argOffset)\n internal\n pure\n returns (address arg)\n {\n uint256 offset = _getImmutableArgsOffset();\n // solhint-disable-next-line no-inline-assembly\n assembly {\n arg := shr(0x60, calldataload(add(offset, argOffset)))\n }\n }\n\n /// @notice Reads an immutable arg with type uint256\n /// @param argOffset The offset of the arg in the packed data\n /// @return arg The arg value\n function _getArgUint256(uint256 argOffset)\n internal\n pure\n returns (uint256 arg)\n {\n uint256 offset = _getImmutableArgsOffset();\n // solhint-disable-next-line no-inline-assembly\n assembly {\n arg := calldataload(add(offset, argOffset))\n }\n }\n\n /// @notice Reads a uint256 array stored in the immutable args.\n /// @param argOffset The offset of the arg in the packed data\n /// @param arrLen Number of elements in the array\n /// @return arr The array\n function _getArgUint256Array(uint256 argOffset, uint64 arrLen)\n internal\n pure\n returns (uint256[] memory arr)\n {\n uint256 offset = _getImmutableArgsOffset();\n uint256 el;\n arr = new uint256[](arrLen);\n for (uint64 i = 0; i < arrLen; i++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n el := calldataload(add(add(offset, argOffset), mul(i, 32)))\n }\n arr[i] = el;\n }\n return arr;\n }\n\n /// @notice Reads an immutable arg with type uint64\n /// @param argOffset The offset of the arg in the packed data\n /// @return arg The arg value\n function _getArgUint64(uint256 argOffset)\n internal\n pure\n returns (uint64 arg)\n {\n uint256 offset = _getImmutableArgsOffset();\n // solhint-disable-next-line no-inline-assembly\n assembly {\n arg := shr(0xc0, calldataload(add(offset, argOffset)))\n }\n }\n\n /// @notice Reads an immutable arg with type uint8\n /// @param argOffset The offset of the arg in the packed data\n /// @return arg The arg value\n function _getArgUint8(uint256 argOffset) internal pure returns (uint8 arg) {\n uint256 offset = _getImmutableArgsOffset();\n // solhint-disable-next-line no-inline-assembly\n assembly {\n arg := shr(0xf8, calldataload(add(offset, argOffset)))\n }\n }\n\n /// @return offset The offset of the packed immutable args in calldata\n function _getImmutableArgsOffset() internal pure returns (uint256 offset) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n offset := sub(\n calldatasize(),\n add(shr(240, calldataload(sub(calldatasize(), 2))), 2)\n )\n }\n }\n}\n" + }, + "clones-with-immutable-args/src/ClonesWithImmutableArgs.sol": { + "content": "// SPDX-License-Identifier: BSD\n\npragma solidity ^0.8.4;\n\n/// @title ClonesWithImmutableArgs\n/// @author wighawag, zefram.eth, nick.eth\n/// @notice Enables creating clone contracts with immutable args\nlibrary ClonesWithImmutableArgs {\n /// @dev The CREATE3 proxy bytecode.\n uint256 private constant _CREATE3_PROXY_BYTECODE =\n 0x67363d3d37363d34f03d5260086018f3;\n\n /// @dev Hash of the `_CREATE3_PROXY_BYTECODE`.\n /// Equivalent to `keccak256(abi.encodePacked(hex\"67363d3d37363d34f03d5260086018f3\"))`.\n bytes32 private constant _CREATE3_PROXY_BYTECODE_HASH =\n 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f;\n\n error CreateFail();\n error InitializeFail();\n\n enum CloneType {\n CREATE,\n CREATE2,\n PREDICT_CREATE2\n }\n\n /// @notice Creates a clone proxy of the implementation contract, with immutable args\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return instance The address of the created clone\n function clone(address implementation, bytes memory data)\n internal\n returns (address payable instance)\n {\n bytes memory creationcode = getCreationBytecode(implementation, data);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n instance := create(0, add(creationcode, 0x20), mload(creationcode))\n }\n if (instance == address(0)) {\n revert CreateFail();\n }\n }\n\n /// @notice Creates a clone proxy of the implementation contract, with immutable args,\n /// using CREATE2\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return instance The address of the created clone\n function clone2(address implementation, bytes memory data)\n internal\n returns (address payable instance)\n {\n bytes memory creationcode = getCreationBytecode(implementation, data);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n instance := create2(0, add(creationcode, 0x20), mload(creationcode), 0)\n }\n if (instance == address(0)) {\n revert CreateFail();\n }\n }\n\n /// @notice Computes the address of a clone created using CREATE2\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return instance The address of the clone\n function addressOfClone2(address implementation, bytes memory data)\n internal\n view\n returns (address payable instance)\n {\n bytes memory creationcode = getCreationBytecode(implementation, data);\n bytes32 bytecodeHash = keccak256(creationcode);\n instance = payable(address(uint160(uint(keccak256(abi.encodePacked(\n bytes1(0xff),\n address(this),\n bytes32(0),\n bytecodeHash\n ))))));\n }\n\n /// @notice Computes bytecode for a clone\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return ret Creation bytecode for the clone contract\n function getCreationBytecode(address implementation, bytes memory data) internal pure returns (bytes memory ret) {\n // unrealistic for memory ptr or data length to exceed 256 bits\n unchecked {\n uint256 extraLength = data.length + 2; // +2 bytes for telling how much data there is appended to the call\n uint256 creationSize = 0x41 + extraLength;\n uint256 runSize = creationSize - 10;\n uint256 dataPtr;\n uint256 ptr;\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ret := mload(0x40)\n mstore(ret, creationSize)\n mstore(0x40, add(ret, creationSize))\n ptr := add(ret, 0x20)\n\n // -------------------------------------------------------------------------------------------------------------\n // CREATION (10 bytes)\n // -------------------------------------------------------------------------------------------------------------\n\n // 61 runtime | PUSH2 runtime (r) | r | –\n mstore(\n ptr,\n 0x6100000000000000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x01), shl(240, runSize)) // size of the contract running bytecode (16 bits)\n\n // creation size = 0a\n // 3d | RETURNDATASIZE | 0 r | –\n // 81 | DUP2 | r 0 r | –\n // 60 creation | PUSH1 creation (c) | c r 0 r | –\n // 3d | RETURNDATASIZE | 0 c r 0 r | –\n // 39 | CODECOPY | 0 r | [0-runSize): runtime code\n // f3 | RETURN | | [0-runSize): runtime code\n\n // -------------------------------------------------------------------------------------------------------------\n // RUNTIME (55 bytes + extraLength)\n // -------------------------------------------------------------------------------------------------------------\n\n // 3d | RETURNDATASIZE | 0 | –\n // 3d | RETURNDATASIZE | 0 0 | –\n // 3d | RETURNDATASIZE | 0 0 0 | –\n // 3d | RETURNDATASIZE | 0 0 0 0 | –\n // 36 | CALLDATASIZE | cds 0 0 0 0 | –\n // 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | –\n // 3d | RETURNDATASIZE | 0 0 cds 0 0 0 0 | –\n // 37 | CALLDATACOPY | 0 0 0 0 | [0, cds) = calldata\n // 61 | PUSH2 extra | extra 0 0 0 0 | [0, cds) = calldata\n mstore(\n add(ptr, 0x03),\n 0x3d81600a3d39f33d3d3d3d363d3d376100000000000000000000000000000000\n )\n mstore(add(ptr, 0x13), shl(240, extraLength))\n\n // 60 0x37 | PUSH1 0x37 | 0x37 extra 0 0 0 0 | [0, cds) = calldata // 0x37 (55) is runtime size - data\n // 36 | CALLDATASIZE | cds 0x37 extra 0 0 0 0 | [0, cds) = calldata\n // 39 | CODECOPY | 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 36 | CALLDATASIZE | cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 61 extra | PUSH2 extra | extra cds 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n mstore(\n add(ptr, 0x15),\n 0x6037363936610000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x1b), shl(240, extraLength))\n\n // 01 | ADD | cds+extra 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 3d | RETURNDATASIZE | 0 cds+extra 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 73 addr | PUSH20 0x123… | addr 0 cds+extra 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n mstore(\n add(ptr, 0x1d),\n 0x013d730000000000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x20), shl(0x60, implementation))\n\n // 5a | GAS | gas addr 0 cds+extra 0 0 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // f4 | DELEGATECALL | success 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 3d | RETURNDATASIZE | rds success 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 3d | RETURNDATASIZE | rds rds success 0 0 | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 93 | SWAP4 | 0 rds success 0 rds | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 80 | DUP1 | 0 0 rds success 0 rds | [0, cds) = calldata, [cds, cds+extra) = extraData\n // 3e | RETURNDATACOPY | success 0 rds | [0, rds) = return data (there might be some irrelevant leftovers in memory [rds, cds+0x37) when rds < cds+0x37)\n // 60 0x35 | PUSH1 0x35 | 0x35 sucess 0 rds | [0, rds) = return data\n // 57 | JUMPI | 0 rds | [0, rds) = return data\n // fd | REVERT | – | [0, rds) = return data\n // 5b | JUMPDEST | 0 rds | [0, rds) = return data\n // f3 | RETURN | – | [0, rds) = return data\n mstore(\n add(ptr, 0x34),\n 0x5af43d3d93803e603557fd5bf300000000000000000000000000000000000000\n )\n }\n\n // -------------------------------------------------------------------------------------------------------------\n // APPENDED DATA (Accessible from extcodecopy)\n // (but also send as appended data to the delegatecall)\n // -------------------------------------------------------------------------------------------------------------\n\n extraLength -= 2;\n uint256 counter = extraLength;\n uint256 copyPtr = ptr + 0x41;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n dataPtr := add(data, 32)\n }\n for (; counter >= 32; counter -= 32) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, mload(dataPtr))\n }\n\n copyPtr += 32;\n dataPtr += 32;\n }\n uint256 mask = ~(256**(32 - counter) - 1);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, and(mload(dataPtr), mask))\n }\n copyPtr += counter;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, shl(240, extraLength))\n }\n }\n }\n\n /// @notice Creates a clone proxy of the implementation contract, with immutable args. Uses CREATE3\n /// to implement deterministic deployment.\n /// @dev data cannot exceed 65535 bytes, since 2 bytes are used to store the data length\n /// @param implementation The implementation contract to clone\n /// @param data Encoded immutable args\n /// @return deployed The address of the created clone\n function clone3(\n address implementation,\n bytes memory data,\n bytes32 salt\n ) internal returns (address deployed) {\n // unrealistic for memory ptr or data length to exceed 256 bits\n unchecked {\n uint256 extraLength = data.length + 2; // +2 bytes for telling how much data there is appended to the call\n uint256 creationSize = 0x43 + extraLength;\n uint256 ptr;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n ptr := mload(0x40)\n\n // -------------------------------------------------------------------------------------------------------------\n // CREATION (11 bytes)\n // -------------------------------------------------------------------------------------------------------------\n\n // 3d | RETURNDATASIZE | 0 | –\n // 61 runtime | PUSH2 runtime (r) | r 0 | –\n mstore(\n ptr,\n 0x3d61000000000000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x02), shl(240, sub(creationSize, 11))) // size of the contract running bytecode (16 bits)\n\n // creation size = 0b\n // 80 | DUP1 | r r 0 | –\n // 60 creation | PUSH1 creation (c) | c r r 0 | –\n // 3d | RETURNDATASIZE | 0 c r r 0 | –\n // 39 | CODECOPY | r 0 | [0-2d]: runtime code\n // 81 | DUP2 | 0 c 0 | [0-2d]: runtime code\n // f3 | RETURN | 0 | [0-2d]: runtime code\n mstore(\n add(ptr, 0x04),\n 0x80600b3d3981f300000000000000000000000000000000000000000000000000\n )\n\n // -------------------------------------------------------------------------------------------------------------\n // RUNTIME\n // -------------------------------------------------------------------------------------------------------------\n\n // 36 | CALLDATASIZE | cds | –\n // 3d | RETURNDATASIZE | 0 cds | –\n // 3d | RETURNDATASIZE | 0 0 cds | –\n // 37 | CALLDATACOPY | – | [0, cds] = calldata\n // 61 | PUSH2 extra | extra | [0, cds] = calldata\n mstore(\n add(ptr, 0x0b),\n 0x363d3d3761000000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x10), shl(240, extraLength))\n\n // 60 0x38 | PUSH1 0x38 | 0x38 extra | [0, cds] = calldata // 0x38 (56) is runtime size - data\n // 36 | CALLDATASIZE | cds 0x38 extra | [0, cds] = calldata\n // 39 | CODECOPY | _ | [0, cds] = calldata\n // 3d | RETURNDATASIZE | 0 | [0, cds] = calldata\n // 3d | RETURNDATASIZE | 0 0 | [0, cds] = calldata\n // 3d | RETURNDATASIZE | 0 0 0 | [0, cds] = calldata\n // 36 | CALLDATASIZE | cds 0 0 0 | [0, cds] = calldata\n // 61 extra | PUSH2 extra | extra cds 0 0 0 | [0, cds] = calldata\n mstore(\n add(ptr, 0x12),\n 0x603836393d3d3d36610000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x1b), shl(240, extraLength))\n\n // 01 | ADD | cds+extra 0 0 0 | [0, cds] = calldata\n // 3d | RETURNDATASIZE | 0 cds 0 0 0 | [0, cds] = calldata\n // 73 addr | PUSH20 0x123… | addr 0 cds 0 0 0 | [0, cds] = calldata\n mstore(\n add(ptr, 0x1d),\n 0x013d730000000000000000000000000000000000000000000000000000000000\n )\n mstore(add(ptr, 0x20), shl(0x60, implementation))\n\n // 5a | GAS | gas addr 0 cds 0 0 0 | [0, cds] = calldata\n // f4 | DELEGATECALL | success 0 | [0, cds] = calldata\n // 3d | RETURNDATASIZE | rds success 0 | [0, cds] = calldata\n // 82 | DUP3 | 0 rds success 0 | [0, cds] = calldata\n // 80 | DUP1 | 0 0 rds success 0 | [0, cds] = calldata\n // 3e | RETURNDATACOPY | success 0 | [0, rds] = return data (there might be some irrelevant leftovers in memory [rds, cds] when rds < cds)\n // 90 | SWAP1 | 0 success | [0, rds] = return data\n // 3d | RETURNDATASIZE | rds 0 success | [0, rds] = return data\n // 91 | SWAP2 | success 0 rds | [0, rds] = return data\n // 60 0x36 | PUSH1 0x36 | 0x36 sucess 0 rds | [0, rds] = return data\n // 57 | JUMPI | 0 rds | [0, rds] = return data\n // fd | REVERT | – | [0, rds] = return data\n // 5b | JUMPDEST | 0 rds | [0, rds] = return data\n // f3 | RETURN | – | [0, rds] = return data\n\n mstore(\n add(ptr, 0x34),\n 0x5af43d82803e903d91603657fd5bf30000000000000000000000000000000000\n )\n }\n\n // -------------------------------------------------------------------------------------------------------------\n // APPENDED DATA (Accessible from extcodecopy)\n // (but also send as appended data to the delegatecall)\n // -------------------------------------------------------------------------------------------------------------\n\n extraLength -= 2;\n uint256 counter = extraLength;\n uint256 copyPtr = ptr + 0x43;\n uint256 dataPtr;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n dataPtr := add(data, 32)\n }\n for (; counter >= 32; counter -= 32) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, mload(dataPtr))\n }\n\n copyPtr += 32;\n dataPtr += 32;\n }\n uint256 mask = ~(256**(32 - counter) - 1);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, and(mload(dataPtr), mask))\n }\n copyPtr += counter;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(copyPtr, shl(240, extraLength))\n }\n\n /// @solidity memory-safe-assembly\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Store the `_PROXY_BYTECODE` into scratch space.\n mstore(0x00, _CREATE3_PROXY_BYTECODE)\n // Deploy a new contract with our pre-made bytecode via CREATE2.\n let proxy := create2(0, 0x10, 0x10, salt)\n\n // If the result of `create2` is the zero address, revert.\n if iszero(proxy) {\n // Store the function selector of `CreateFail()`.\n mstore(0x00, 0xebfef188)\n // Revert with (offset, size).\n revert(0x1c, 0x04)\n }\n\n // Store the proxy's address.\n mstore(0x14, proxy)\n // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01).\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex).\n mstore(0x00, 0xd694)\n // Nonce of the proxy contract (1).\n mstore8(0x34, 0x01)\n\n deployed := keccak256(0x1e, 0x17)\n\n // If the `call` fails or the code size of `deployed` is zero, revert.\n // The second argument of the or() call is evaluated first, which is important\n // here because extcodesize(deployed) is only non-zero after the call() to the proxy\n // is made and the contract is successfully deployed.\n if or(\n iszero(extcodesize(deployed)),\n iszero(\n call(\n gas(), // Gas remaining.\n proxy, // Proxy's address.\n 0, // Ether value.\n ptr, // Pointer to the creation code\n creationSize, // Size of the creation code\n 0x00, // Offset of output.\n 0x00 // Length of output.\n )\n )\n ) {\n // Store the function selector of `InitializeFail()`.\n mstore(0x00, 0x8f86d2f1)\n // Revert with (offset, size).\n revert(0x1c, 0x04)\n }\n }\n }\n }\n\n /// @notice Returns the CREATE3 deterministic address of the contract deployed via cloneDeterministic().\n /// @dev Forked from https://github.com/Vectorized/solady/blob/main/src/utils/CREATE3.sol\n /// @param salt The salt used by the CREATE3 deployment\n function addressOfClone3(bytes32 salt)\n internal\n view\n returns (address deployed)\n {\n /// @solidity memory-safe-assembly\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Cache the free memory pointer.\n let m := mload(0x40)\n // Store `address(this)`.\n mstore(0x00, address())\n // Store the prefix.\n mstore8(0x0b, 0xff)\n // Store the salt.\n mstore(0x20, salt)\n // Store the bytecode hash.\n mstore(0x40, _CREATE3_PROXY_BYTECODE_HASH)\n\n // Store the proxy's address.\n mstore(0x14, keccak256(0x0b, 0x55))\n // Restore the free memory pointer.\n mstore(0x40, m)\n // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01).\n // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex).\n mstore(0x00, 0xd694)\n // Nonce of the proxy contract (1).\n mstore8(0x34, 0x01)\n\n deployed := keccak256(0x1e, 0x17)\n }\n }\n}\n" + }, + "contracts/dnsregistrar/DNSClaimChecker.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../dnssec-oracle/DNSSEC.sol\";\nimport \"../dnssec-oracle/RRUtils.sol\";\nimport \"../utils/BytesUtils.sol\";\nimport \"../utils/HexUtils.sol\";\nimport \"@ensdomains/buffer/contracts/Buffer.sol\";\n\nlibrary DNSClaimChecker {\n using BytesUtils for bytes;\n using HexUtils for bytes;\n using RRUtils for *;\n using Buffer for Buffer.buffer;\n\n uint16 constant CLASS_INET = 1;\n uint16 constant TYPE_TXT = 16;\n\n function getOwnerAddress(\n bytes memory name,\n bytes memory data\n ) internal pure returns (address, bool) {\n // Add \"_ens.\" to the front of the name.\n Buffer.buffer memory buf;\n buf.init(name.length + 5);\n buf.append(\"\\x04_ens\");\n buf.append(name);\n\n for (\n RRUtils.RRIterator memory iter = data.iterateRRs(0);\n !iter.done();\n iter.next()\n ) {\n if (iter.name().compareNames(buf.buf) != 0) continue;\n bool found;\n address addr;\n (addr, found) = parseRR(data, iter.rdataOffset, iter.nextOffset);\n if (found) {\n return (addr, true);\n }\n }\n\n return (address(0x0), false);\n }\n\n function parseRR(\n bytes memory rdata,\n uint256 idx,\n uint256 endIdx\n ) internal pure returns (address, bool) {\n while (idx < endIdx) {\n uint256 len = rdata.readUint8(idx);\n idx += 1;\n\n bool found;\n address addr;\n (addr, found) = parseString(rdata, idx, len);\n\n if (found) return (addr, true);\n idx += len;\n }\n\n return (address(0x0), false);\n }\n\n function parseString(\n bytes memory str,\n uint256 idx,\n uint256 len\n ) internal pure returns (address, bool) {\n // TODO: More robust parsing that handles whitespace and multiple key/value pairs\n if (str.readUint32(idx) != 0x613d3078) return (address(0x0), false); // 0x613d3078 == 'a=0x'\n return str.hexToAddress(idx + 4, idx + len);\n }\n}\n" + }, + "contracts/dnsregistrar/DNSRegistrar.sol": { + "content": "//SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@ensdomains/buffer/contracts/Buffer.sol\";\nimport \"../dnssec-oracle/DNSSEC.sol\";\nimport \"../dnssec-oracle/RRUtils.sol\";\nimport \"../registry/ENSRegistry.sol\";\nimport \"../root/Root.sol\";\nimport \"../resolvers/profiles/AddrResolver.sol\";\nimport \"../utils/BytesUtils.sol\";\nimport \"./DNSClaimChecker.sol\";\nimport \"./PublicSuffixList.sol\";\nimport \"./IDNSRegistrar.sol\";\n\n/**\n * @dev An ENS registrar that allows the owner of a DNS name to claim the\n * corresponding name in ENS.\n */\ncontract DNSRegistrar is IDNSRegistrar, IERC165 {\n using BytesUtils for bytes;\n using Buffer for Buffer.buffer;\n using RRUtils for *;\n\n ENS public immutable ens;\n DNSSEC public immutable oracle;\n PublicSuffixList public suffixes;\n address public immutable previousRegistrar;\n address public immutable resolver;\n // A mapping of the most recent signatures seen for each claimed domain.\n mapping(bytes32 => uint32) public inceptions;\n\n error NoOwnerRecordFound();\n error PermissionDenied(address caller, address owner);\n error PreconditionNotMet();\n error StaleProof();\n error InvalidPublicSuffix(bytes name);\n\n struct OwnerRecord {\n bytes name;\n address owner;\n address resolver;\n uint64 ttl;\n }\n\n event Claim(\n bytes32 indexed node,\n address indexed owner,\n bytes dnsname,\n uint32 inception\n );\n event NewPublicSuffixList(address suffixes);\n\n constructor(\n address _previousRegistrar,\n address _resolver,\n DNSSEC _dnssec,\n PublicSuffixList _suffixes,\n ENS _ens\n ) {\n previousRegistrar = _previousRegistrar;\n resolver = _resolver;\n oracle = _dnssec;\n suffixes = _suffixes;\n emit NewPublicSuffixList(address(suffixes));\n ens = _ens;\n }\n\n /**\n * @dev This contract's owner-only functions can be invoked by the owner of the ENS root.\n */\n modifier onlyOwner() {\n Root root = Root(ens.owner(bytes32(0)));\n address owner = root.owner();\n require(msg.sender == owner);\n _;\n }\n\n function setPublicSuffixList(PublicSuffixList _suffixes) public onlyOwner {\n suffixes = _suffixes;\n emit NewPublicSuffixList(address(suffixes));\n }\n\n /**\n * @dev Submits proofs to the DNSSEC oracle, then claims a name using those proofs.\n * @param name The name to claim, in DNS wire format.\n * @param input A chain of signed DNS RRSETs ending with a text record.\n */\n function proveAndClaim(\n bytes memory name,\n DNSSEC.RRSetWithSignature[] memory input\n ) public override {\n (bytes32 rootNode, bytes32 labelHash, address addr) = _claim(\n name,\n input\n );\n ens.setSubnodeOwner(rootNode, labelHash, addr);\n }\n\n function proveAndClaimWithResolver(\n bytes memory name,\n DNSSEC.RRSetWithSignature[] memory input,\n address resolver,\n address addr\n ) public override {\n (bytes32 rootNode, bytes32 labelHash, address owner) = _claim(\n name,\n input\n );\n if (msg.sender != owner) {\n revert PermissionDenied(msg.sender, owner);\n }\n ens.setSubnodeRecord(rootNode, labelHash, owner, resolver, 0);\n if (addr != address(0)) {\n if (resolver == address(0)) {\n revert PreconditionNotMet();\n }\n bytes32 node = keccak256(abi.encodePacked(rootNode, labelHash));\n // Set the resolver record\n AddrResolver(resolver).setAddr(node, addr);\n }\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) external pure override returns (bool) {\n return\n interfaceID == type(IERC165).interfaceId ||\n interfaceID == type(IDNSRegistrar).interfaceId;\n }\n\n function _claim(\n bytes memory name,\n DNSSEC.RRSetWithSignature[] memory input\n ) internal returns (bytes32 parentNode, bytes32 labelHash, address addr) {\n (bytes memory data, uint32 inception) = oracle.verifyRRSet(input);\n\n // Get the first label\n uint256 labelLen = name.readUint8(0);\n labelHash = name.keccak(1, labelLen);\n\n bytes memory parentName = name.substring(\n labelLen + 1,\n name.length - labelLen - 1\n );\n\n // Make sure the parent name is enabled\n parentNode = enableNode(parentName);\n\n bytes32 node = keccak256(abi.encodePacked(parentNode, labelHash));\n if (!RRUtils.serialNumberGte(inception, inceptions[node])) {\n revert StaleProof();\n }\n inceptions[node] = inception;\n\n bool found;\n (addr, found) = DNSClaimChecker.getOwnerAddress(name, data);\n if (!found) {\n revert NoOwnerRecordFound();\n }\n\n emit Claim(node, addr, name, inception);\n }\n\n function enableNode(bytes memory domain) public returns (bytes32 node) {\n // Name must be in the public suffix list.\n if (!suffixes.isPublicSuffix(domain)) {\n revert InvalidPublicSuffix(domain);\n }\n return _enableNode(domain, 0);\n }\n\n function _enableNode(\n bytes memory domain,\n uint256 offset\n ) internal returns (bytes32 node) {\n uint256 len = domain.readUint8(offset);\n if (len == 0) {\n return bytes32(0);\n }\n\n bytes32 parentNode = _enableNode(domain, offset + len + 1);\n bytes32 label = domain.keccak(offset + 1, len);\n node = keccak256(abi.encodePacked(parentNode, label));\n address owner = ens.owner(node);\n if (owner == address(0) || owner == previousRegistrar) {\n if (parentNode == bytes32(0)) {\n Root root = Root(ens.owner(bytes32(0)));\n root.setSubnodeOwner(label, address(this));\n ens.setResolver(node, resolver);\n } else {\n ens.setSubnodeRecord(\n parentNode,\n label,\n address(this),\n resolver,\n 0\n );\n }\n } else if (owner != address(this)) {\n revert PreconditionNotMet();\n }\n return node;\n }\n}\n" + }, + "contracts/dnsregistrar/IDNSRegistrar.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../dnssec-oracle/DNSSEC.sol\";\n\ninterface IDNSRegistrar {\n function proveAndClaim(\n bytes memory name,\n DNSSEC.RRSetWithSignature[] memory input\n ) external;\n\n function proveAndClaimWithResolver(\n bytes memory name,\n DNSSEC.RRSetWithSignature[] memory input,\n address resolver,\n address addr\n ) external;\n}\n" + }, + "contracts/dnsregistrar/PublicSuffixList.sol": { + "content": "pragma solidity ^0.8.4;\n\ninterface PublicSuffixList {\n function isPublicSuffix(bytes calldata name) external view returns (bool);\n}\n" + }, + "contracts/dnssec-oracle/DNSSEC.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\npragma experimental ABIEncoderV2;\n\nabstract contract DNSSEC {\n bytes public anchors;\n\n struct RRSetWithSignature {\n bytes rrset;\n bytes sig;\n }\n\n event AlgorithmUpdated(uint8 id, address addr);\n event DigestUpdated(uint8 id, address addr);\n\n function verifyRRSet(\n RRSetWithSignature[] memory input\n ) external view virtual returns (bytes memory rrs, uint32 inception);\n\n function verifyRRSet(\n RRSetWithSignature[] memory input,\n uint256 now\n ) public view virtual returns (bytes memory rrs, uint32 inception);\n}\n" + }, + "contracts/dnssec-oracle/RRUtils.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"../utils/BytesUtils.sol\";\nimport \"@ensdomains/buffer/contracts/Buffer.sol\";\n\n/**\n * @dev RRUtils is a library that provides utilities for parsing DNS resource records.\n */\nlibrary RRUtils {\n using BytesUtils for *;\n using Buffer for *;\n\n /**\n * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'.\n * @param self The byte array to read a name from.\n * @param offset The offset to start reading at.\n * @return The length of the DNS name at 'offset', in bytes.\n */\n function nameLength(\n bytes memory self,\n uint256 offset\n ) internal pure returns (uint256) {\n uint256 idx = offset;\n while (true) {\n assert(idx < self.length);\n uint256 labelLen = self.readUint8(idx);\n idx += labelLen + 1;\n if (labelLen == 0) {\n break;\n }\n }\n return idx - offset;\n }\n\n /**\n * @dev Returns a DNS format name at the specified offset of self.\n * @param self The byte array to read a name from.\n * @param offset The offset to start reading at.\n * @return ret The name.\n */\n function readName(\n bytes memory self,\n uint256 offset\n ) internal pure returns (bytes memory ret) {\n uint256 len = nameLength(self, offset);\n return self.substring(offset, len);\n }\n\n /**\n * @dev Returns the number of labels in the DNS name at 'offset' in 'self'.\n * @param self The byte array to read a name from.\n * @param offset The offset to start reading at.\n * @return The number of labels in the DNS name at 'offset', in bytes.\n */\n function labelCount(\n bytes memory self,\n uint256 offset\n ) internal pure returns (uint256) {\n uint256 count = 0;\n while (true) {\n assert(offset < self.length);\n uint256 labelLen = self.readUint8(offset);\n offset += labelLen + 1;\n if (labelLen == 0) {\n break;\n }\n count += 1;\n }\n return count;\n }\n\n uint256 constant RRSIG_TYPE = 0;\n uint256 constant RRSIG_ALGORITHM = 2;\n uint256 constant RRSIG_LABELS = 3;\n uint256 constant RRSIG_TTL = 4;\n uint256 constant RRSIG_EXPIRATION = 8;\n uint256 constant RRSIG_INCEPTION = 12;\n uint256 constant RRSIG_KEY_TAG = 16;\n uint256 constant RRSIG_SIGNER_NAME = 18;\n\n struct SignedSet {\n uint16 typeCovered;\n uint8 algorithm;\n uint8 labels;\n uint32 ttl;\n uint32 expiration;\n uint32 inception;\n uint16 keytag;\n bytes signerName;\n bytes data;\n bytes name;\n }\n\n function readSignedSet(\n bytes memory data\n ) internal pure returns (SignedSet memory self) {\n self.typeCovered = data.readUint16(RRSIG_TYPE);\n self.algorithm = data.readUint8(RRSIG_ALGORITHM);\n self.labels = data.readUint8(RRSIG_LABELS);\n self.ttl = data.readUint32(RRSIG_TTL);\n self.expiration = data.readUint32(RRSIG_EXPIRATION);\n self.inception = data.readUint32(RRSIG_INCEPTION);\n self.keytag = data.readUint16(RRSIG_KEY_TAG);\n self.signerName = readName(data, RRSIG_SIGNER_NAME);\n self.data = data.substring(\n RRSIG_SIGNER_NAME + self.signerName.length,\n data.length - RRSIG_SIGNER_NAME - self.signerName.length\n );\n }\n\n function rrs(\n SignedSet memory rrset\n ) internal pure returns (RRIterator memory) {\n return iterateRRs(rrset.data, 0);\n }\n\n /**\n * @dev An iterator over resource records.\n */\n struct RRIterator {\n bytes data;\n uint256 offset;\n uint16 dnstype;\n uint16 class;\n uint32 ttl;\n uint256 rdataOffset;\n uint256 nextOffset;\n }\n\n /**\n * @dev Begins iterating over resource records.\n * @param self The byte string to read from.\n * @param offset The offset to start reading at.\n * @return ret An iterator object.\n */\n function iterateRRs(\n bytes memory self,\n uint256 offset\n ) internal pure returns (RRIterator memory ret) {\n ret.data = self;\n ret.nextOffset = offset;\n next(ret);\n }\n\n /**\n * @dev Returns true iff there are more RRs to iterate.\n * @param iter The iterator to check.\n * @return True iff the iterator has finished.\n */\n function done(RRIterator memory iter) internal pure returns (bool) {\n return iter.offset >= iter.data.length;\n }\n\n /**\n * @dev Moves the iterator to the next resource record.\n * @param iter The iterator to advance.\n */\n function next(RRIterator memory iter) internal pure {\n iter.offset = iter.nextOffset;\n if (iter.offset >= iter.data.length) {\n return;\n }\n\n // Skip the name\n uint256 off = iter.offset + nameLength(iter.data, iter.offset);\n\n // Read type, class, and ttl\n iter.dnstype = iter.data.readUint16(off);\n off += 2;\n iter.class = iter.data.readUint16(off);\n off += 2;\n iter.ttl = iter.data.readUint32(off);\n off += 4;\n\n // Read the rdata\n uint256 rdataLength = iter.data.readUint16(off);\n off += 2;\n iter.rdataOffset = off;\n iter.nextOffset = off + rdataLength;\n }\n\n /**\n * @dev Returns the name of the current record.\n * @param iter The iterator.\n * @return A new bytes object containing the owner name from the RR.\n */\n function name(RRIterator memory iter) internal pure returns (bytes memory) {\n return\n iter.data.substring(\n iter.offset,\n nameLength(iter.data, iter.offset)\n );\n }\n\n /**\n * @dev Returns the rdata portion of the current record.\n * @param iter The iterator.\n * @return A new bytes object containing the RR's RDATA.\n */\n function rdata(\n RRIterator memory iter\n ) internal pure returns (bytes memory) {\n return\n iter.data.substring(\n iter.rdataOffset,\n iter.nextOffset - iter.rdataOffset\n );\n }\n\n uint256 constant DNSKEY_FLAGS = 0;\n uint256 constant DNSKEY_PROTOCOL = 2;\n uint256 constant DNSKEY_ALGORITHM = 3;\n uint256 constant DNSKEY_PUBKEY = 4;\n\n struct DNSKEY {\n uint16 flags;\n uint8 protocol;\n uint8 algorithm;\n bytes publicKey;\n }\n\n function readDNSKEY(\n bytes memory data,\n uint256 offset,\n uint256 length\n ) internal pure returns (DNSKEY memory self) {\n self.flags = data.readUint16(offset + DNSKEY_FLAGS);\n self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL);\n self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM);\n self.publicKey = data.substring(\n offset + DNSKEY_PUBKEY,\n length - DNSKEY_PUBKEY\n );\n }\n\n uint256 constant DS_KEY_TAG = 0;\n uint256 constant DS_ALGORITHM = 2;\n uint256 constant DS_DIGEST_TYPE = 3;\n uint256 constant DS_DIGEST = 4;\n\n struct DS {\n uint16 keytag;\n uint8 algorithm;\n uint8 digestType;\n bytes digest;\n }\n\n function readDS(\n bytes memory data,\n uint256 offset,\n uint256 length\n ) internal pure returns (DS memory self) {\n self.keytag = data.readUint16(offset + DS_KEY_TAG);\n self.algorithm = data.readUint8(offset + DS_ALGORITHM);\n self.digestType = data.readUint8(offset + DS_DIGEST_TYPE);\n self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST);\n }\n\n function isSubdomainOf(\n bytes memory self,\n bytes memory other\n ) internal pure returns (bool) {\n uint256 off = 0;\n uint256 counts = labelCount(self, 0);\n uint256 othercounts = labelCount(other, 0);\n\n while (counts > othercounts) {\n off = progress(self, off);\n counts--;\n }\n\n return self.equals(off, other, 0);\n }\n\n function compareNames(\n bytes memory self,\n bytes memory other\n ) internal pure returns (int256) {\n if (self.equals(other)) {\n return 0;\n }\n\n uint256 off;\n uint256 otheroff;\n uint256 prevoff;\n uint256 otherprevoff;\n uint256 counts = labelCount(self, 0);\n uint256 othercounts = labelCount(other, 0);\n\n // Keep removing labels from the front of the name until both names are equal length\n while (counts > othercounts) {\n prevoff = off;\n off = progress(self, off);\n counts--;\n }\n\n while (othercounts > counts) {\n otherprevoff = otheroff;\n otheroff = progress(other, otheroff);\n othercounts--;\n }\n\n // Compare the last nonequal labels to each other\n while (counts > 0 && !self.equals(off, other, otheroff)) {\n prevoff = off;\n off = progress(self, off);\n otherprevoff = otheroff;\n otheroff = progress(other, otheroff);\n counts -= 1;\n }\n\n if (off == 0) {\n return -1;\n }\n if (otheroff == 0) {\n return 1;\n }\n\n return\n self.compare(\n prevoff + 1,\n self.readUint8(prevoff),\n other,\n otherprevoff + 1,\n other.readUint8(otherprevoff)\n );\n }\n\n /**\n * @dev Compares two serial numbers using RFC1982 serial number math.\n */\n function serialNumberGte(\n uint32 i1,\n uint32 i2\n ) internal pure returns (bool) {\n unchecked {\n return int32(i1) - int32(i2) >= 0;\n }\n }\n\n function progress(\n bytes memory body,\n uint256 off\n ) internal pure returns (uint256) {\n return off + 1 + body.readUint8(off);\n }\n\n /**\n * @dev Computes the keytag for a chunk of data.\n * @param data The data to compute a keytag for.\n * @return The computed key tag.\n */\n function computeKeytag(bytes memory data) internal pure returns (uint16) {\n /* This function probably deserves some explanation.\n * The DNSSEC keytag function is a checksum that relies on summing up individual bytes\n * from the input string, with some mild bitshifting. Here's a Naive solidity implementation:\n *\n * function computeKeytag(bytes memory data) internal pure returns (uint16) {\n * uint ac;\n * for (uint i = 0; i < data.length; i++) {\n * ac += i & 1 == 0 ? uint16(data.readUint8(i)) << 8 : data.readUint8(i);\n * }\n * return uint16(ac + (ac >> 16));\n * }\n *\n * The EVM, with its 256 bit words, is exceedingly inefficient at doing byte-by-byte operations;\n * the code above, on reasonable length inputs, consumes over 100k gas. But we can make the EVM's\n * large words work in our favour.\n *\n * The code below works by treating the input as a series of 256 bit words. It first masks out\n * even and odd bytes from each input word, adding them to two separate accumulators `ac1` and `ac2`.\n * The bytes are separated by empty bytes, so as long as no individual sum exceeds 2^16-1, we're\n * effectively summing 16 different numbers with each EVM ADD opcode.\n *\n * Once it's added up all the inputs, it has to add all the 16 bit values in `ac1` and `ac2` together.\n * It does this using the same trick - mask out every other value, shift to align them, add them together.\n * After the first addition on both accumulators, there's enough room to add the two accumulators together,\n * and the remaining sums can be done just on ac1.\n */\n unchecked {\n require(data.length <= 8192, \"Long keys not permitted\");\n uint256 ac1;\n uint256 ac2;\n for (uint256 i = 0; i < data.length + 31; i += 32) {\n uint256 word;\n assembly {\n word := mload(add(add(data, 32), i))\n }\n if (i + 32 > data.length) {\n uint256 unused = 256 - (data.length - i) * 8;\n word = (word >> unused) << unused;\n }\n ac1 +=\n (word &\n 0xFF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00) >>\n 8;\n ac2 += (word &\n 0x00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF);\n }\n ac1 =\n (ac1 &\n 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) +\n ((ac1 &\n 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >>\n 16);\n ac2 =\n (ac2 &\n 0x0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF) +\n ((ac2 &\n 0xFFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000) >>\n 16);\n ac1 = (ac1 << 8) + ac2;\n ac1 =\n (ac1 &\n 0x00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF) +\n ((ac1 &\n 0xFFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000FFFFFFFF00000000) >>\n 32);\n ac1 =\n (ac1 &\n 0x0000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF) +\n ((ac1 &\n 0xFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF0000000000000000) >>\n 64);\n ac1 =\n (ac1 &\n 0x00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +\n (ac1 >> 128);\n ac1 += (ac1 >> 16) & 0xFFFF;\n return uint16(ac1);\n }\n }\n}\n" + }, + "contracts/ethregistrar/BaseRegistrarImplementation.sol": { + "content": "pragma solidity >=0.8.4;\n\nimport \"../registry/ENS.sol\";\nimport \"./IBaseRegistrar.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/ERC721.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract BaseRegistrarImplementation is ERC721, IBaseRegistrar, Ownable {\n // A map of expiry times\n mapping(uint256 => uint256) expiries;\n // The ENS registry\n ENS public ens;\n // The namehash of the TLD this registrar owns (eg, .eth)\n bytes32 public baseNode;\n // A map of addresses that are authorised to register and renew names.\n mapping(address => bool) public controllers;\n uint256 public constant GRACE_PERIOD = 90 days;\n bytes4 private constant INTERFACE_META_ID =\n bytes4(keccak256(\"supportsInterface(bytes4)\"));\n bytes4 private constant ERC721_ID =\n bytes4(\n keccak256(\"balanceOf(address)\") ^\n keccak256(\"ownerOf(uint256)\") ^\n keccak256(\"approve(address,uint256)\") ^\n keccak256(\"getApproved(uint256)\") ^\n keccak256(\"setApprovalForAll(address,bool)\") ^\n keccak256(\"isApprovedForAll(address,address)\") ^\n keccak256(\"transferFrom(address,address,uint256)\") ^\n keccak256(\"safeTransferFrom(address,address,uint256)\") ^\n keccak256(\"safeTransferFrom(address,address,uint256,bytes)\")\n );\n bytes4 private constant RECLAIM_ID =\n bytes4(keccak256(\"reclaim(uint256,address)\"));\n\n /**\n * v2.1.3 version of _isApprovedOrOwner which calls ownerOf(tokenId) and takes grace period into consideration instead of ERC721.ownerOf(tokenId);\n * https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.1.3/contracts/token/ERC721/ERC721.sol#L187\n * @dev Returns whether the given spender can transfer a given token ID\n * @param spender address of the spender to query\n * @param tokenId uint256 ID of the token to be transferred\n * @return bool whether the msg.sender is approved for the given token ID,\n * is an operator of the owner, or is the owner of the token\n */\n function _isApprovedOrOwner(\n address spender,\n uint256 tokenId\n ) internal view override returns (bool) {\n address owner = ownerOf(tokenId);\n return (spender == owner ||\n getApproved(tokenId) == spender ||\n isApprovedForAll(owner, spender));\n }\n\n constructor(ENS _ens, bytes32 _baseNode) ERC721(\"\", \"\") {\n ens = _ens;\n baseNode = _baseNode;\n }\n\n modifier live() {\n require(ens.owner(baseNode) == address(this));\n _;\n }\n\n modifier onlyController() {\n require(controllers[msg.sender]);\n _;\n }\n\n /**\n * @dev Gets the owner of the specified token ID. Names become unowned\n * when their registration expires.\n * @param tokenId uint256 ID of the token to query the owner of\n * @return address currently marked as the owner of the given token ID\n */\n function ownerOf(\n uint256 tokenId\n ) public view override(IERC721, ERC721) returns (address) {\n require(expiries[tokenId] > block.timestamp);\n return super.ownerOf(tokenId);\n }\n\n // Authorises a controller, who can register and renew domains.\n function addController(address controller) external override onlyOwner {\n controllers[controller] = true;\n emit ControllerAdded(controller);\n }\n\n // Revoke controller permission for an address.\n function removeController(address controller) external override onlyOwner {\n controllers[controller] = false;\n emit ControllerRemoved(controller);\n }\n\n // Set the resolver for the TLD this registrar manages.\n function setResolver(address resolver) external override onlyOwner {\n ens.setResolver(baseNode, resolver);\n }\n\n // Returns the expiration timestamp of the specified id.\n function nameExpires(uint256 id) external view override returns (uint256) {\n return expiries[id];\n }\n\n // Returns true iff the specified name is available for registration.\n function available(uint256 id) public view override returns (bool) {\n // Not available if it's registered here or in its grace period.\n return expiries[id] + GRACE_PERIOD < block.timestamp;\n }\n\n /**\n * @dev Register a name.\n * @param id The token ID (keccak256 of the label).\n * @param owner The address that should own the registration.\n * @param duration Duration in seconds for the registration.\n */\n function register(\n uint256 id,\n address owner,\n uint256 duration\n ) external override returns (uint256) {\n return _register(id, owner, duration, true);\n }\n\n /**\n * @dev Register a name, without modifying the registry.\n * @param id The token ID (keccak256 of the label).\n * @param owner The address that should own the registration.\n * @param duration Duration in seconds for the registration.\n */\n function registerOnly(\n uint256 id,\n address owner,\n uint256 duration\n ) external returns (uint256) {\n return _register(id, owner, duration, false);\n }\n\n function _register(\n uint256 id,\n address owner,\n uint256 duration,\n bool updateRegistry\n ) internal live onlyController returns (uint256) {\n require(available(id));\n require(\n block.timestamp + duration + GRACE_PERIOD >\n block.timestamp + GRACE_PERIOD\n ); // Prevent future overflow\n\n expiries[id] = block.timestamp + duration;\n if (_exists(id)) {\n // Name was previously owned, and expired\n _burn(id);\n }\n _mint(owner, id);\n if (updateRegistry) {\n ens.setSubnodeOwner(baseNode, bytes32(id), owner);\n }\n\n emit NameRegistered(id, owner, block.timestamp + duration);\n\n return block.timestamp + duration;\n }\n\n function renew(\n uint256 id,\n uint256 duration\n ) external override live onlyController returns (uint256) {\n require(expiries[id] + GRACE_PERIOD >= block.timestamp); // Name must be registered here or in grace period\n require(\n expiries[id] + duration + GRACE_PERIOD > duration + GRACE_PERIOD\n ); // Prevent future overflow\n\n expiries[id] += duration;\n emit NameRenewed(id, expiries[id]);\n return expiries[id];\n }\n\n /**\n * @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\n */\n function reclaim(uint256 id, address owner) external override live {\n require(_isApprovedOrOwner(msg.sender, id));\n ens.setSubnodeOwner(baseNode, bytes32(id), owner);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view override(ERC721, IERC165) returns (bool) {\n return\n interfaceID == INTERFACE_META_ID ||\n interfaceID == ERC721_ID ||\n interfaceID == RECLAIM_ID;\n }\n}\n" + }, + "contracts/ethregistrar/BulkRenewal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"../registry/ENS.sol\";\nimport \"./ETHRegistrarController.sol\";\nimport \"./IETHRegistrarController.sol\";\nimport \"../resolvers/Resolver.sol\";\nimport \"./IBulkRenewal.sol\";\nimport \"./IPriceOracle.sol\";\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract BulkRenewal is IBulkRenewal {\n bytes32 private constant ETH_NAMEHASH =\n 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;\n\n ENS public immutable ens;\n\n constructor(ENS _ens) {\n ens = _ens;\n }\n\n function getController() internal view returns (ETHRegistrarController) {\n Resolver r = Resolver(ens.resolver(ETH_NAMEHASH));\n return\n ETHRegistrarController(\n r.interfaceImplementer(\n ETH_NAMEHASH,\n type(IETHRegistrarController).interfaceId\n )\n );\n }\n\n function rentPrice(\n string[] calldata names,\n uint256 duration\n ) external view override returns (uint256 total) {\n ETHRegistrarController controller = getController();\n uint256 length = names.length;\n for (uint256 i = 0; i < length; ) {\n IPriceOracle.Price memory price = controller.rentPrice(\n names[i],\n duration\n );\n unchecked {\n ++i;\n total += (price.base + price.premium);\n }\n }\n }\n\n function renewAll(\n string[] calldata names,\n uint256 duration\n ) external payable override {\n ETHRegistrarController controller = getController();\n uint256 length = names.length;\n uint256 total;\n for (uint256 i = 0; i < length; ) {\n IPriceOracle.Price memory price = controller.rentPrice(\n names[i],\n duration\n );\n uint256 totalPrice = price.base + price.premium;\n controller.renew{value: totalPrice}(names[i], duration);\n unchecked {\n ++i;\n total += totalPrice;\n }\n }\n // Send any excess funds back\n payable(msg.sender).transfer(address(this).balance);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) external pure returns (bool) {\n return\n interfaceID == type(IERC165).interfaceId ||\n interfaceID == type(IBulkRenewal).interfaceId;\n }\n}\n" + }, + "contracts/ethregistrar/ETHRegistrarController.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport {BaseRegistrarImplementation} from \"./BaseRegistrarImplementation.sol\";\nimport {StringUtils} from \"../utils/StringUtils.sol\";\nimport {Resolver} from \"../resolvers/Resolver.sol\";\nimport {ENS} from \"../registry/ENS.sol\";\nimport {ReverseRegistrar} from \"../reverseRegistrar/ReverseRegistrar.sol\";\nimport {ReverseClaimer} from \"../reverseRegistrar/ReverseClaimer.sol\";\nimport {IETHRegistrarController, IPriceOracle} from \"./IETHRegistrarController.sol\";\n\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Address} from \"@openzeppelin/contracts/utils/Address.sol\";\nimport {INameWrapper} from \"../wrapper/INameWrapper.sol\";\nimport {ERC20Recoverable} from \"../utils/ERC20Recoverable.sol\";\n\nerror CommitmentTooNew(bytes32 commitment);\nerror CommitmentTooOld(bytes32 commitment);\nerror NameNotAvailable(string name);\nerror DurationTooShort(uint256 duration);\nerror ResolverRequiredWhenDataSupplied();\nerror UnexpiredCommitmentExists(bytes32 commitment);\nerror InsufficientValue();\nerror Unauthorised(bytes32 node);\nerror MaxCommitmentAgeTooLow();\nerror MaxCommitmentAgeTooHigh();\n\n/**\n * @dev A registrar controller for registering and renewing names at fixed cost.\n */\ncontract ETHRegistrarController is\n Ownable,\n IETHRegistrarController,\n IERC165,\n ERC20Recoverable,\n ReverseClaimer\n{\n using StringUtils for *;\n using Address for address;\n\n uint256 public constant MIN_REGISTRATION_DURATION = 28 days;\n bytes32 private constant ETH_NODE =\n 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae;\n uint64 private constant MAX_EXPIRY = type(uint64).max;\n BaseRegistrarImplementation immutable base;\n IPriceOracle public immutable prices;\n uint256 public immutable minCommitmentAge;\n uint256 public immutable maxCommitmentAge;\n ReverseRegistrar public immutable reverseRegistrar;\n INameWrapper public immutable nameWrapper;\n\n mapping(bytes32 => uint256) public commitments;\n\n event NameRegistered(\n string name,\n bytes32 indexed label,\n address indexed owner,\n uint256 baseCost,\n uint256 premium,\n uint256 expires\n );\n event NameRenewed(\n string name,\n bytes32 indexed label,\n uint256 cost,\n uint256 expires\n );\n\n constructor(\n BaseRegistrarImplementation _base,\n IPriceOracle _prices,\n uint256 _minCommitmentAge,\n uint256 _maxCommitmentAge,\n ReverseRegistrar _reverseRegistrar,\n INameWrapper _nameWrapper,\n ENS _ens\n ) ReverseClaimer(_ens, msg.sender) {\n if (_maxCommitmentAge <= _minCommitmentAge) {\n revert MaxCommitmentAgeTooLow();\n }\n\n if (_maxCommitmentAge > block.timestamp) {\n revert MaxCommitmentAgeTooHigh();\n }\n\n base = _base;\n prices = _prices;\n minCommitmentAge = _minCommitmentAge;\n maxCommitmentAge = _maxCommitmentAge;\n reverseRegistrar = _reverseRegistrar;\n nameWrapper = _nameWrapper;\n }\n\n function rentPrice(\n string memory name,\n uint256 duration\n ) public view override returns (IPriceOracle.Price memory price) {\n bytes32 label = keccak256(bytes(name));\n price = prices.price(name, base.nameExpires(uint256(label)), duration);\n }\n\n function valid(string memory name) public pure returns (bool) {\n return name.strlen() >= 3;\n }\n\n function available(string memory name) public view override returns (bool) {\n bytes32 label = keccak256(bytes(name));\n return valid(name) && base.available(uint256(label));\n }\n\n function makeCommitment(\n string memory name,\n address owner,\n uint256 duration,\n bytes32 secret,\n address resolver,\n bytes[] calldata data,\n bool reverseRecord,\n uint16 ownerControlledFuses\n ) public pure override returns (bytes32) {\n bytes32 label = keccak256(bytes(name));\n if (data.length > 0 && resolver == address(0)) {\n revert ResolverRequiredWhenDataSupplied();\n }\n return\n keccak256(\n abi.encode(\n label,\n owner,\n duration,\n secret,\n resolver,\n data,\n reverseRecord,\n ownerControlledFuses\n )\n );\n }\n\n function commit(bytes32 commitment) public override {\n if (commitments[commitment] + maxCommitmentAge >= block.timestamp) {\n revert UnexpiredCommitmentExists(commitment);\n }\n commitments[commitment] = block.timestamp;\n }\n\n function register(\n string calldata name,\n address owner,\n uint256 duration,\n bytes32 secret,\n address resolver,\n bytes[] calldata data,\n bool reverseRecord,\n uint16 ownerControlledFuses\n ) public payable override {\n IPriceOracle.Price memory price = rentPrice(name, duration);\n if (msg.value < price.base + price.premium) {\n revert InsufficientValue();\n }\n\n _consumeCommitment(\n name,\n duration,\n makeCommitment(\n name,\n owner,\n duration,\n secret,\n resolver,\n data,\n reverseRecord,\n ownerControlledFuses\n )\n );\n\n uint256 expires = nameWrapper.registerAndWrapETH2LD(\n name,\n owner,\n duration,\n resolver,\n ownerControlledFuses\n );\n\n if (data.length > 0) {\n _setRecords(resolver, keccak256(bytes(name)), data);\n }\n\n if (reverseRecord) {\n _setReverseRecord(name, resolver, msg.sender);\n }\n\n emit NameRegistered(\n name,\n keccak256(bytes(name)),\n owner,\n price.base,\n price.premium,\n expires\n );\n\n if (msg.value > (price.base + price.premium)) {\n payable(msg.sender).transfer(\n msg.value - (price.base + price.premium)\n );\n }\n }\n\n function renew(\n string calldata name,\n uint256 duration\n ) external payable override {\n bytes32 labelhash = keccak256(bytes(name));\n uint256 tokenId = uint256(labelhash);\n IPriceOracle.Price memory price = rentPrice(name, duration);\n if (msg.value < price.base) {\n revert InsufficientValue();\n }\n uint256 expires = nameWrapper.renew(tokenId, duration);\n\n if (msg.value > price.base) {\n payable(msg.sender).transfer(msg.value - price.base);\n }\n\n emit NameRenewed(name, labelhash, msg.value, expires);\n }\n\n function withdraw() public {\n payable(owner()).transfer(address(this).balance);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) external pure returns (bool) {\n return\n interfaceID == type(IERC165).interfaceId ||\n interfaceID == type(IETHRegistrarController).interfaceId;\n }\n\n /* Internal functions */\n\n function _consumeCommitment(\n string memory name,\n uint256 duration,\n bytes32 commitment\n ) internal {\n // Require an old enough commitment.\n if (commitments[commitment] + minCommitmentAge > block.timestamp) {\n revert CommitmentTooNew(commitment);\n }\n\n // If the commitment is too old, or the name is registered, stop\n if (commitments[commitment] + maxCommitmentAge <= block.timestamp) {\n revert CommitmentTooOld(commitment);\n }\n if (!available(name)) {\n revert NameNotAvailable(name);\n }\n\n delete (commitments[commitment]);\n\n if (duration < MIN_REGISTRATION_DURATION) {\n revert DurationTooShort(duration);\n }\n }\n\n function _setRecords(\n address resolverAddress,\n bytes32 label,\n bytes[] calldata data\n ) internal {\n // use hardcoded .eth namehash\n bytes32 nodehash = keccak256(abi.encodePacked(ETH_NODE, label));\n Resolver resolver = Resolver(resolverAddress);\n resolver.multicallWithNodeCheck(nodehash, data);\n }\n\n function _setReverseRecord(\n string memory name,\n address resolver,\n address owner\n ) internal {\n reverseRegistrar.setNameForAddr(\n msg.sender,\n owner,\n resolver,\n string.concat(name, \".eth\")\n );\n }\n}\n" + }, + "contracts/ethregistrar/ExponentialPremiumPriceOracle.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"./StablePriceOracle.sol\";\n\ncontract ExponentialPremiumPriceOracle is StablePriceOracle {\n uint256 constant GRACE_PERIOD = 90 days;\n uint256 immutable startPremium;\n uint256 immutable endValue;\n\n constructor(\n AggregatorInterface _usdOracle,\n uint256[] memory _rentPrices,\n uint256 _startPremium,\n uint256 totalDays\n ) StablePriceOracle(_usdOracle, _rentPrices) {\n startPremium = _startPremium;\n endValue = _startPremium >> totalDays;\n }\n\n uint256 constant PRECISION = 1e18;\n uint256 constant bit1 = 999989423469314432; // 0.5 ^ 1/65536 * (10 ** 18)\n uint256 constant bit2 = 999978847050491904; // 0.5 ^ 2/65536 * (10 ** 18)\n uint256 constant bit3 = 999957694548431104;\n uint256 constant bit4 = 999915390886613504;\n uint256 constant bit5 = 999830788931929088;\n uint256 constant bit6 = 999661606496243712;\n uint256 constant bit7 = 999323327502650752;\n uint256 constant bit8 = 998647112890970240;\n uint256 constant bit9 = 997296056085470080;\n uint256 constant bit10 = 994599423483633152;\n uint256 constant bit11 = 989228013193975424;\n uint256 constant bit12 = 978572062087700096;\n uint256 constant bit13 = 957603280698573696;\n uint256 constant bit14 = 917004043204671232;\n uint256 constant bit15 = 840896415253714560;\n uint256 constant bit16 = 707106781186547584;\n\n /**\n * @dev Returns the pricing premium in internal base units.\n */\n function _premium(\n string memory,\n uint256 expires,\n uint256\n ) internal view override returns (uint256) {\n expires = expires + GRACE_PERIOD;\n if (expires > block.timestamp) {\n return 0;\n }\n\n uint256 elapsed = block.timestamp - expires;\n uint256 premium = decayedPremium(startPremium, elapsed);\n if (premium >= endValue) {\n return premium - endValue;\n }\n return 0;\n }\n\n /**\n * @dev Returns the premium price at current time elapsed\n * @param startPremium starting price\n * @param elapsed time past since expiry\n */\n function decayedPremium(\n uint256 startPremium,\n uint256 elapsed\n ) public pure returns (uint256) {\n uint256 daysPast = (elapsed * PRECISION) / 1 days;\n uint256 intDays = daysPast / PRECISION;\n uint256 premium = startPremium >> intDays;\n uint256 partDay = (daysPast - intDays * PRECISION);\n uint256 fraction = (partDay * (2 ** 16)) / PRECISION;\n uint256 totalPremium = addFractionalPremium(fraction, premium);\n return totalPremium;\n }\n\n function addFractionalPremium(\n uint256 fraction,\n uint256 premium\n ) internal pure returns (uint256) {\n if (fraction & (1 << 0) != 0) {\n premium = (premium * bit1) / PRECISION;\n }\n if (fraction & (1 << 1) != 0) {\n premium = (premium * bit2) / PRECISION;\n }\n if (fraction & (1 << 2) != 0) {\n premium = (premium * bit3) / PRECISION;\n }\n if (fraction & (1 << 3) != 0) {\n premium = (premium * bit4) / PRECISION;\n }\n if (fraction & (1 << 4) != 0) {\n premium = (premium * bit5) / PRECISION;\n }\n if (fraction & (1 << 5) != 0) {\n premium = (premium * bit6) / PRECISION;\n }\n if (fraction & (1 << 6) != 0) {\n premium = (premium * bit7) / PRECISION;\n }\n if (fraction & (1 << 7) != 0) {\n premium = (premium * bit8) / PRECISION;\n }\n if (fraction & (1 << 8) != 0) {\n premium = (premium * bit9) / PRECISION;\n }\n if (fraction & (1 << 9) != 0) {\n premium = (premium * bit10) / PRECISION;\n }\n if (fraction & (1 << 10) != 0) {\n premium = (premium * bit11) / PRECISION;\n }\n if (fraction & (1 << 11) != 0) {\n premium = (premium * bit12) / PRECISION;\n }\n if (fraction & (1 << 12) != 0) {\n premium = (premium * bit13) / PRECISION;\n }\n if (fraction & (1 << 13) != 0) {\n premium = (premium * bit14) / PRECISION;\n }\n if (fraction & (1 << 14) != 0) {\n premium = (premium * bit15) / PRECISION;\n }\n if (fraction & (1 << 15) != 0) {\n premium = (premium * bit16) / PRECISION;\n }\n return premium;\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/ethregistrar/IBaseRegistrar.sol": { + "content": "import \"../registry/ENS.sol\";\nimport \"./IBaseRegistrar.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721.sol\";\n\ninterface IBaseRegistrar is IERC721 {\n event ControllerAdded(address indexed controller);\n event ControllerRemoved(address indexed controller);\n event NameMigrated(\n uint256 indexed id,\n address indexed owner,\n uint256 expires\n );\n event NameRegistered(\n uint256 indexed id,\n address indexed owner,\n uint256 expires\n );\n event NameRenewed(uint256 indexed id, uint256 expires);\n\n // Authorises a controller, who can register and renew domains.\n function addController(address controller) external;\n\n // Revoke controller permission for an address.\n function removeController(address controller) external;\n\n // Set the resolver for the TLD this registrar manages.\n function setResolver(address resolver) external;\n\n // Returns the expiration timestamp of the specified label hash.\n function nameExpires(uint256 id) external view returns (uint256);\n\n // Returns true if the specified name is available for registration.\n function available(uint256 id) external view returns (bool);\n\n /**\n * @dev Register a name.\n */\n function register(\n uint256 id,\n address owner,\n uint256 duration\n ) external returns (uint256);\n\n function renew(uint256 id, uint256 duration) external returns (uint256);\n\n /**\n * @dev Reclaim ownership of a name in ENS, if you own it in the registrar.\n */\n function reclaim(uint256 id, address owner) external;\n}\n" + }, + "contracts/ethregistrar/IBulkRenewal.sol": { + "content": "interface IBulkRenewal {\n function rentPrice(\n string[] calldata names,\n uint256 duration\n ) external view returns (uint256 total);\n\n function renewAll(\n string[] calldata names,\n uint256 duration\n ) external payable;\n}\n" + }, + "contracts/ethregistrar/IETHRegistrarController.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"./IPriceOracle.sol\";\n\ninterface IETHRegistrarController {\n function rentPrice(\n string memory,\n uint256\n ) external view returns (IPriceOracle.Price memory);\n\n function available(string memory) external returns (bool);\n\n function makeCommitment(\n string memory,\n address,\n uint256,\n bytes32,\n address,\n bytes[] calldata,\n bool,\n uint16\n ) external pure returns (bytes32);\n\n function commit(bytes32) external;\n\n function register(\n string calldata,\n address,\n uint256,\n bytes32,\n address,\n bytes[] calldata,\n bool,\n uint16\n ) external payable;\n\n function renew(string calldata, uint256) external payable;\n}\n" + }, + "contracts/ethregistrar/IPriceOracle.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.17 <0.9.0;\n\ninterface IPriceOracle {\n struct Price {\n uint256 base;\n uint256 premium;\n }\n\n /**\n * @dev Returns the price to register or renew a name.\n * @param name The name being registered or renewed.\n * @param expires When the name presently expires (0 if this is a new registration).\n * @param duration How long the name is being registered or extended for, in seconds.\n * @return base premium tuple of base price + premium price\n */\n function price(\n string calldata name,\n uint256 expires,\n uint256 duration\n ) external view returns (Price calldata);\n}\n" + }, + "contracts/ethregistrar/LinearPremiumPriceOracle.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"./SafeMath.sol\";\nimport \"./StablePriceOracle.sol\";\n\ncontract LinearPremiumPriceOracle is StablePriceOracle {\n using SafeMath for *;\n\n uint256 immutable GRACE_PERIOD = 90 days;\n\n uint256 public immutable initialPremium;\n uint256 public immutable premiumDecreaseRate;\n\n bytes4 private constant TIME_UNTIL_PREMIUM_ID =\n bytes4(keccak256(\"timeUntilPremium(uint,uint\"));\n\n constructor(\n AggregatorInterface _usdOracle,\n uint256[] memory _rentPrices,\n uint256 _initialPremium,\n uint256 _premiumDecreaseRate\n ) public StablePriceOracle(_usdOracle, _rentPrices) {\n initialPremium = _initialPremium;\n premiumDecreaseRate = _premiumDecreaseRate;\n }\n\n function _premium(\n string memory name,\n uint256 expires,\n uint256 /*duration*/\n ) internal view override returns (uint256) {\n expires = expires.add(GRACE_PERIOD);\n if (expires > block.timestamp) {\n // No premium for renewals\n return 0;\n }\n\n // Calculate the discount off the maximum premium\n uint256 discount = premiumDecreaseRate.mul(\n block.timestamp.sub(expires)\n );\n\n // If we've run out the premium period, return 0.\n if (discount > initialPremium) {\n return 0;\n }\n\n return initialPremium - discount;\n }\n\n /**\n * @dev Returns the timestamp at which a name with the specified expiry date will have\n * the specified re-registration price premium.\n * @param expires The timestamp at which the name expires.\n * @param amount The amount, in wei, the caller is willing to pay\n * @return The timestamp at which the premium for this domain will be `amount`.\n */\n function timeUntilPremium(\n uint256 expires,\n uint256 amount\n ) external view returns (uint256) {\n amount = weiToAttoUSD(amount);\n require(amount <= initialPremium);\n\n expires = expires.add(GRACE_PERIOD);\n\n uint256 discount = initialPremium.sub(amount);\n uint256 duration = discount.div(premiumDecreaseRate);\n return expires.add(duration);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n (interfaceID == TIME_UNTIL_PREMIUM_ID) ||\n super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/ethregistrar/SafeMath.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\n/**\n * @title SafeMath\n * @dev Unsigned math operations with safety checks that revert on error\n */\nlibrary SafeMath {\n /**\n * @dev Multiplies two unsigned integers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b > 0);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two unsigned integers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),\n * reverts when dividing by zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b != 0);\n return a % b;\n }\n}\n" + }, + "contracts/ethregistrar/StablePriceOracle.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"./IPriceOracle.sol\";\nimport \"../utils/StringUtils.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ninterface AggregatorInterface {\n function latestAnswer() external view returns (int256);\n}\n\n// StablePriceOracle sets a price in USD, based on an oracle.\ncontract StablePriceOracle is IPriceOracle {\n using StringUtils for *;\n\n // Rent in base price units by length\n uint256 public immutable price1Letter;\n uint256 public immutable price2Letter;\n uint256 public immutable price3Letter;\n uint256 public immutable price4Letter;\n uint256 public immutable price5Letter;\n\n // Oracle address\n AggregatorInterface public immutable usdOracle;\n\n event RentPriceChanged(uint256[] prices);\n\n constructor(AggregatorInterface _usdOracle, uint256[] memory _rentPrices) {\n usdOracle = _usdOracle;\n price1Letter = _rentPrices[0];\n price2Letter = _rentPrices[1];\n price3Letter = _rentPrices[2];\n price4Letter = _rentPrices[3];\n price5Letter = _rentPrices[4];\n }\n\n function price(\n string calldata name,\n uint256 expires,\n uint256 duration\n ) external view override returns (IPriceOracle.Price memory) {\n uint256 len = name.strlen();\n uint256 basePrice;\n\n if (len >= 5) {\n basePrice = price5Letter * duration;\n } else if (len == 4) {\n basePrice = price4Letter * duration;\n } else if (len == 3) {\n basePrice = price3Letter * duration;\n } else if (len == 2) {\n basePrice = price2Letter * duration;\n } else {\n basePrice = price1Letter * duration;\n }\n\n return\n IPriceOracle.Price({\n base: attoUSDToWei(basePrice),\n premium: attoUSDToWei(_premium(name, expires, duration))\n });\n }\n\n /**\n * @dev Returns the pricing premium in wei.\n */\n function premium(\n string calldata name,\n uint256 expires,\n uint256 duration\n ) external view returns (uint256) {\n return attoUSDToWei(_premium(name, expires, duration));\n }\n\n /**\n * @dev Returns the pricing premium in internal base units.\n */\n function _premium(\n string memory name,\n uint256 expires,\n uint256 duration\n ) internal view virtual returns (uint256) {\n return 0;\n }\n\n function attoUSDToWei(uint256 amount) internal view returns (uint256) {\n uint256 ethPrice = uint256(usdOracle.latestAnswer());\n return (amount * 1e8) / ethPrice;\n }\n\n function weiToAttoUSD(uint256 amount) internal view returns (uint256) {\n uint256 ethPrice = uint256(usdOracle.latestAnswer());\n return (amount * ethPrice) / 1e8;\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual returns (bool) {\n return\n interfaceID == type(IERC165).interfaceId ||\n interfaceID == type(IPriceOracle).interfaceId;\n }\n}\n" + }, + "contracts/ethregistrar/StaticBulkRenewal.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity ~0.8.17;\n\nimport \"./ETHRegistrarController.sol\";\nimport \"./IBulkRenewal.sol\";\nimport \"./IPriceOracle.sol\";\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\ncontract StaticBulkRenewal is IBulkRenewal {\n ETHRegistrarController controller;\n\n constructor(ETHRegistrarController _controller) {\n controller = _controller;\n }\n\n function rentPrice(\n string[] calldata names,\n uint256 duration\n ) external view override returns (uint256 total) {\n uint256 length = names.length;\n for (uint256 i = 0; i < length; ) {\n IPriceOracle.Price memory price = controller.rentPrice(\n names[i],\n duration\n );\n unchecked {\n ++i;\n total += (price.base + price.premium);\n }\n }\n }\n\n function renewAll(\n string[] calldata names,\n uint256 duration\n ) external payable override {\n uint256 length = names.length;\n uint256 total;\n for (uint256 i = 0; i < length; ) {\n IPriceOracle.Price memory price = controller.rentPrice(\n names[i],\n duration\n );\n uint256 totalPrice = price.base + price.premium;\n controller.renew{value: totalPrice}(names[i], duration);\n unchecked {\n ++i;\n total += totalPrice;\n }\n }\n // Send any excess funds back\n payable(msg.sender).transfer(address(this).balance);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) external pure returns (bool) {\n return\n interfaceID == type(IERC165).interfaceId ||\n interfaceID == type(IBulkRenewal).interfaceId;\n }\n}\n" + }, + "contracts/registry/ENS.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma 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/registry/ENSRegistry.sol": { + "content": "pragma solidity >=0.8.4;\n\nimport \"./ENS.sol\";\n\n/**\n * The ENS registry contract.\n */\ncontract ENSRegistry is ENS {\n struct Record {\n address owner;\n address resolver;\n uint64 ttl;\n }\n\n mapping(bytes32 => Record) records;\n mapping(address => mapping(address => bool)) operators;\n\n // Permits modifications only by the owner of the specified node.\n modifier authorised(bytes32 node) {\n address owner = records[node].owner;\n require(owner == msg.sender || operators[owner][msg.sender]);\n _;\n }\n\n /**\n * @dev Constructs a new ENS registry.\n */\n constructor() public {\n records[0x0].owner = msg.sender;\n }\n\n /**\n * @dev Sets the record for a node.\n * @param node The node to update.\n * @param owner The address of the new owner.\n * @param resolver The address of the resolver.\n * @param ttl The TTL in seconds.\n */\n function setRecord(\n bytes32 node,\n address owner,\n address resolver,\n uint64 ttl\n ) external virtual override {\n setOwner(node, owner);\n _setResolverAndTTL(node, resolver, ttl);\n }\n\n /**\n * @dev Sets the record for a subnode.\n * @param node The parent node.\n * @param label The hash of the label specifying the subnode.\n * @param owner The address of the new owner.\n * @param resolver The address of the resolver.\n * @param ttl The TTL in seconds.\n */\n function setSubnodeRecord(\n bytes32 node,\n bytes32 label,\n address owner,\n address resolver,\n uint64 ttl\n ) external virtual override {\n bytes32 subnode = setSubnodeOwner(node, label, owner);\n _setResolverAndTTL(subnode, resolver, ttl);\n }\n\n /**\n * @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.\n * @param node The node to transfer ownership of.\n * @param owner The address of the new owner.\n */\n function setOwner(\n bytes32 node,\n address owner\n ) public virtual override authorised(node) {\n _setOwner(node, owner);\n emit Transfer(node, owner);\n }\n\n /**\n * @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.\n * @param node The parent node.\n * @param label The hash of the label specifying the subnode.\n * @param owner The address of the new owner.\n */\n function setSubnodeOwner(\n bytes32 node,\n bytes32 label,\n address owner\n ) public virtual override authorised(node) returns (bytes32) {\n bytes32 subnode = keccak256(abi.encodePacked(node, label));\n _setOwner(subnode, owner);\n emit NewOwner(node, label, owner);\n return subnode;\n }\n\n /**\n * @dev Sets the resolver address for the specified node.\n * @param node The node to update.\n * @param resolver The address of the resolver.\n */\n function setResolver(\n bytes32 node,\n address resolver\n ) public virtual override authorised(node) {\n emit NewResolver(node, resolver);\n records[node].resolver = resolver;\n }\n\n /**\n * @dev Sets the TTL for the specified node.\n * @param node The node to update.\n * @param ttl The TTL in seconds.\n */\n function setTTL(\n bytes32 node,\n uint64 ttl\n ) public virtual override authorised(node) {\n emit NewTTL(node, ttl);\n records[node].ttl = ttl;\n }\n\n /**\n * @dev Enable or disable approval for a third party (\"operator\") to manage\n * all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.\n * @param operator Address to add to the set of authorized operators.\n * @param approved True if the operator is approved, false to revoke approval.\n */\n function setApprovalForAll(\n address operator,\n bool approved\n ) external virtual override {\n operators[msg.sender][operator] = approved;\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n /**\n * @dev Returns the address that owns the specified node.\n * @param node The specified node.\n * @return address of the owner.\n */\n function owner(\n bytes32 node\n ) public view virtual override returns (address) {\n address addr = records[node].owner;\n if (addr == address(this)) {\n return address(0x0);\n }\n\n return addr;\n }\n\n /**\n * @dev Returns the address of the resolver for the specified node.\n * @param node The specified node.\n * @return address of the resolver.\n */\n function resolver(\n bytes32 node\n ) public view virtual override returns (address) {\n return records[node].resolver;\n }\n\n /**\n * @dev Returns the TTL of a node, and any records associated with it.\n * @param node The specified node.\n * @return ttl of the node.\n */\n function ttl(bytes32 node) public view virtual override returns (uint64) {\n return records[node].ttl;\n }\n\n /**\n * @dev Returns whether a record has been imported to the registry.\n * @param node The specified node.\n * @return Bool if record exists\n */\n function recordExists(\n bytes32 node\n ) public view virtual override returns (bool) {\n return records[node].owner != address(0x0);\n }\n\n /**\n * @dev Query if an address is an authorized operator for another address.\n * @param owner The address that owns the records.\n * @param operator The address that acts on behalf of the owner.\n * @return True if `operator` is an approved operator for `owner`, false otherwise.\n */\n function isApprovedForAll(\n address owner,\n address operator\n ) external view virtual override returns (bool) {\n return operators[owner][operator];\n }\n\n function _setOwner(bytes32 node, address owner) internal virtual {\n records[node].owner = owner;\n }\n\n function _setResolverAndTTL(\n bytes32 node,\n address resolver,\n uint64 ttl\n ) internal {\n if (resolver != records[node].resolver) {\n records[node].resolver = resolver;\n emit NewResolver(node, resolver);\n }\n\n if (ttl != records[node].ttl) {\n records[node].ttl = ttl;\n emit NewTTL(node, ttl);\n }\n }\n}\n" + }, + "contracts/resolvers/DelegatableResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {Clone} from \"clones-with-immutable-args/src/Clone.sol\";\n\nimport \"./profiles/ABIResolver.sol\";\nimport \"./profiles/AddrResolver.sol\";\nimport \"./profiles/ContentHashResolver.sol\";\nimport \"./profiles/DNSResolver.sol\";\nimport \"./profiles/InterfaceResolver.sol\";\nimport \"./profiles/NameResolver.sol\";\nimport \"./profiles/PubkeyResolver.sol\";\nimport \"./profiles/TextResolver.sol\";\nimport \"./profiles/ExtendedResolver.sol\";\nimport \"./Multicallable.sol\";\nimport \"./IDelegatableResolver.sol\";\n\n/**\n * A delegated resolver that allows the resolver owner to add an operator to update records of a node on behalf of the owner.\n * address.\n */\ncontract DelegatableResolver is\n Clone,\n Multicallable,\n ABIResolver,\n AddrResolver,\n ContentHashResolver,\n DNSResolver,\n InterfaceResolver,\n NameResolver,\n PubkeyResolver,\n TextResolver,\n ExtendedResolver\n{\n using BytesUtils for bytes;\n\n // Logged when an operator is added or removed.\n event Approval(\n bytes32 indexed node,\n address indexed operator,\n bytes name,\n bool approved\n );\n\n error NotAuthorized(bytes32 node);\n\n //node => (delegate => isAuthorised)\n mapping(bytes32 => mapping(address => bool)) operators;\n\n /*\n * Check to see if the operator has been approved by the owner for the node.\n * @param name The ENS node to query\n * @param offset The offset of the label to query recursively. Start from the 0 position and kepp adding the length of each label as it traverse. The function exits when len is 0.\n * @param operator The address of the operator to query\n * @return node The node of the name passed as an argument\n * @return authorized The boolean state of whether the operator is approved to update record of the name\n */\n function getAuthorisedNode(\n bytes memory name,\n uint256 offset,\n address operator\n ) public view returns (bytes32 node, bool authorized) {\n uint256 len = name.readUint8(offset);\n node = bytes32(0);\n if (len > 0) {\n bytes32 label = name.keccak(offset + 1, len);\n (node, authorized) = getAuthorisedNode(\n name,\n offset + len + 1,\n operator\n );\n node = keccak256(abi.encodePacked(node, label));\n } else {\n return (\n node,\n authorized || operators[node][operator] || owner() == operator\n );\n }\n return (node, authorized || operators[node][operator]);\n }\n\n /**\n * @dev Approve an operator to be able to updated records on a node.\n */\n function approve(\n bytes memory name,\n address operator,\n bool approved\n ) external {\n (bytes32 node, bool authorized) = getAuthorisedNode(\n name,\n 0,\n msg.sender\n );\n if (!authorized) {\n revert NotAuthorized(node);\n }\n operators[node][operator] = approved;\n emit Approval(node, operator, name, approved);\n }\n\n /*\n * Returns the owner address passed set by the Factory\n * @return address The owner address\n */\n function owner() public pure returns (address) {\n return _getArgAddress(0);\n }\n\n function isAuthorised(bytes32 node) internal view override returns (bool) {\n return msg.sender == owner() || operators[node][msg.sender];\n }\n\n function supportsInterface(\n bytes4 interfaceID\n )\n public\n view\n virtual\n override(\n Multicallable,\n ABIResolver,\n AddrResolver,\n ContentHashResolver,\n DNSResolver,\n InterfaceResolver,\n NameResolver,\n PubkeyResolver,\n TextResolver\n )\n returns (bool)\n {\n return\n interfaceID == type(IDelegatableResolver).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/resolvers/DelegatableResolverFactory.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport {ClonesWithImmutableArgs} from \"clones-with-immutable-args/src/ClonesWithImmutableArgs.sol\";\n\nimport \"./DelegatableResolver.sol\";\n\n/**\n * A resolver factory that creates a dedicated resolver for each user\n */\n\ncontract DelegatableResolverFactory {\n using ClonesWithImmutableArgs for address;\n\n DelegatableResolver public implementation;\n event NewDelegatableResolver(address resolver, address owner);\n\n constructor(DelegatableResolver _implementation) {\n implementation = _implementation;\n }\n\n /*\n * Create the unique address unique to the owner\n * @param address The address of the resolver owner\n * @return address The address of the newly created Resolver\n */\n function create(\n address owner\n ) external returns (DelegatableResolver clone) {\n bytes memory data = abi.encodePacked(owner);\n clone = DelegatableResolver(address(implementation).clone2(data));\n emit NewDelegatableResolver(address(clone), owner);\n }\n\n /*\n * Returns the unique address unique to the owner\n * @param address The address of the resolver owner\n * @return address The address of the newly created Resolver\n */\n function predictAddress(\n address owner\n ) external view returns (address clone) {\n bytes memory data = abi.encodePacked(owner);\n clone = address(implementation).addressOfClone2(data);\n }\n}\n" + }, + "contracts/resolvers/IDelegatableResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\ninterface IDelegatableResolver {\n function approve(\n bytes memory name,\n address operator,\n bool approved\n ) external;\n\n function getAuthorisedNode(\n bytes memory name,\n uint256 offset,\n address operator\n ) external returns (bytes32 node, bool authorized);\n\n function owner() external view returns (address);\n}\n" + }, + "contracts/resolvers/IMulticallable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IMulticallable {\n function multicall(\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n\n function multicallWithNodeCheck(\n bytes32,\n bytes[] calldata data\n ) external returns (bytes[] memory results);\n}\n" + }, + "contracts/resolvers/Multicallable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"./IMulticallable.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nabstract contract Multicallable is IMulticallable, ERC165 {\n function _multicall(\n bytes32 nodehash,\n bytes[] calldata data\n ) internal returns (bytes[] memory results) {\n results = new bytes[](data.length);\n for (uint256 i = 0; i < data.length; i++) {\n if (nodehash != bytes32(0)) {\n bytes32 txNamehash = bytes32(data[i][4:36]);\n require(\n txNamehash == nodehash,\n \"multicall: All records must have a matching namehash\"\n );\n }\n (bool success, bytes memory result) = address(this).delegatecall(\n data[i]\n );\n require(success);\n results[i] = result;\n }\n return results;\n }\n\n // This function provides an extra security check when called\n // from priviledged contracts (such as EthRegistrarController)\n // that can set records on behalf of the node owners\n function multicallWithNodeCheck(\n bytes32 nodehash,\n bytes[] calldata data\n ) external returns (bytes[] memory results) {\n return _multicall(nodehash, data);\n }\n\n function multicall(\n bytes[] calldata data\n ) public override returns (bytes[] memory results) {\n return _multicall(bytes32(0), data);\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n interfaceID == type(IMulticallable).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/resolvers/OwnedResolver.sol": { + "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./profiles/ABIResolver.sol\";\nimport \"./profiles/AddrResolver.sol\";\nimport \"./profiles/ContentHashResolver.sol\";\nimport \"./profiles/DNSResolver.sol\";\nimport \"./profiles/InterfaceResolver.sol\";\nimport \"./profiles/NameResolver.sol\";\nimport \"./profiles/PubkeyResolver.sol\";\nimport \"./profiles/TextResolver.sol\";\nimport \"./profiles/ExtendedResolver.sol\";\n\n/**\n * A simple resolver anyone can use; only allows the owner of a node to set its\n * address.\n */\ncontract OwnedResolver is\n Ownable,\n ABIResolver,\n AddrResolver,\n ContentHashResolver,\n DNSResolver,\n InterfaceResolver,\n NameResolver,\n PubkeyResolver,\n TextResolver,\n ExtendedResolver\n{\n function isAuthorised(bytes32) internal view override returns (bool) {\n return msg.sender == owner();\n }\n\n function supportsInterface(\n bytes4 interfaceID\n )\n public\n view\n virtual\n override(\n ABIResolver,\n AddrResolver,\n ContentHashResolver,\n DNSResolver,\n InterfaceResolver,\n NameResolver,\n PubkeyResolver,\n TextResolver\n )\n returns (bool)\n {\n return super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/resolvers/profiles/ABIResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"./IABIResolver.sol\";\nimport \"../ResolverBase.sol\";\n\nabstract contract ABIResolver is IABIResolver, ResolverBase {\n mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_abis;\n\n /**\n * Sets the ABI associated with an ENS node.\n * Nodes may have one ABI of each content type. To remove an ABI, set it to\n * the empty string.\n * @param node The node to update.\n * @param contentType The content type of the ABI\n * @param data The ABI data.\n */\n function setABI(\n bytes32 node,\n uint256 contentType,\n bytes calldata data\n ) external virtual authorised(node) {\n // Content types must be powers of 2\n require(((contentType - 1) & contentType) == 0);\n\n versionable_abis[recordVersions[node]][node][contentType] = data;\n emit ABIChanged(node, contentType);\n }\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 virtual override returns (uint256, bytes memory) {\n mapping(uint256 => bytes) storage abiset = versionable_abis[\n recordVersions[node]\n ][node];\n\n for (\n uint256 contentType = 1;\n contentType <= contentTypes;\n contentType <<= 1\n ) {\n if (\n (contentType & contentTypes) != 0 &&\n abiset[contentType].length > 0\n ) {\n return (contentType, abiset[contentType]);\n }\n }\n\n return (0, bytes(\"\"));\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n interfaceID == type(IABIResolver).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/resolvers/profiles/AddrResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"../ResolverBase.sol\";\nimport \"./IAddrResolver.sol\";\nimport \"./IAddressResolver.sol\";\n\nabstract contract AddrResolver is\n IAddrResolver,\n IAddressResolver,\n ResolverBase\n{\n uint256 private constant COIN_TYPE_ETH = 60;\n\n mapping(uint64 => mapping(bytes32 => mapping(uint256 => bytes))) versionable_addresses;\n\n /**\n * Sets the address associated with an ENS node.\n * May only be called by the owner of that node in the ENS registry.\n * @param node The node to update.\n * @param a The address to set.\n */\n function setAddr(\n bytes32 node,\n address a\n ) external virtual authorised(node) {\n setAddr(node, COIN_TYPE_ETH, addressToBytes(a));\n }\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(\n bytes32 node\n ) public view virtual override returns (address payable) {\n bytes memory a = addr(node, COIN_TYPE_ETH);\n if (a.length == 0) {\n return payable(0);\n }\n return bytesToAddress(a);\n }\n\n function setAddr(\n bytes32 node,\n uint256 coinType,\n bytes memory a\n ) public virtual authorised(node) {\n emit AddressChanged(node, coinType, a);\n if (coinType == COIN_TYPE_ETH) {\n emit AddrChanged(node, bytesToAddress(a));\n }\n versionable_addresses[recordVersions[node]][node][coinType] = a;\n }\n\n function addr(\n bytes32 node,\n uint256 coinType\n ) public view virtual override returns (bytes memory) {\n return versionable_addresses[recordVersions[node]][node][coinType];\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n interfaceID == type(IAddrResolver).interfaceId ||\n interfaceID == type(IAddressResolver).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n\n function bytesToAddress(\n bytes memory b\n ) internal pure returns (address payable a) {\n require(b.length == 20);\n assembly {\n a := div(mload(add(b, 32)), exp(256, 12))\n }\n }\n\n function addressToBytes(address a) internal pure returns (bytes memory b) {\n b = new bytes(20);\n assembly {\n mstore(add(b, 32), mul(a, exp(256, 12)))\n }\n }\n}\n" + }, + "contracts/resolvers/profiles/ContentHashResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"../ResolverBase.sol\";\nimport \"./IContentHashResolver.sol\";\n\nabstract contract ContentHashResolver is IContentHashResolver, ResolverBase {\n mapping(uint64 => mapping(bytes32 => bytes)) versionable_hashes;\n\n /**\n * Sets the contenthash associated with an ENS node.\n * May only be called by the owner of that node in the ENS registry.\n * @param node The node to update.\n * @param hash The contenthash to set\n */\n function setContenthash(\n bytes32 node,\n bytes calldata hash\n ) external virtual authorised(node) {\n versionable_hashes[recordVersions[node]][node] = hash;\n emit ContenthashChanged(node, hash);\n }\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(\n bytes32 node\n ) external view virtual override returns (bytes memory) {\n return versionable_hashes[recordVersions[node]][node];\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n interfaceID == type(IContentHashResolver).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n}\n" + }, + "contracts/resolvers/profiles/DNSResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.4;\n\nimport \"../ResolverBase.sol\";\nimport \"../../dnssec-oracle/RRUtils.sol\";\nimport \"./IDNSRecordResolver.sol\";\nimport \"./IDNSZoneResolver.sol\";\n\nabstract contract DNSResolver is\n IDNSRecordResolver,\n IDNSZoneResolver,\n ResolverBase\n{\n using RRUtils for *;\n using BytesUtils for bytes;\n\n // Zone hashes for the domains.\n // A zone hash is an EIP-1577 content hash in binary format that should point to a\n // resource containing a single zonefile.\n // node => contenthash\n mapping(uint64 => mapping(bytes32 => bytes)) private versionable_zonehashes;\n\n // The records themselves. Stored as binary RRSETs\n // node => version => name => resource => data\n mapping(uint64 => mapping(bytes32 => mapping(bytes32 => mapping(uint16 => bytes))))\n private versionable_records;\n\n // Count of number of entries for a given name. Required for DNS resolvers\n // when resolving wildcards.\n // node => version => name => number of records\n mapping(uint64 => mapping(bytes32 => mapping(bytes32 => uint16)))\n private versionable_nameEntriesCount;\n\n /**\n * Set one or more DNS records. Records are supplied in wire-format.\n * Records with the same node/name/resource must be supplied one after the\n * other to ensure the data is updated correctly. For example, if the data\n * was supplied:\n * a.example.com IN A 1.2.3.4\n * a.example.com IN A 5.6.7.8\n * www.example.com IN CNAME a.example.com.\n * then this would store the two A records for a.example.com correctly as a\n * single RRSET, however if the data was supplied:\n * a.example.com IN A 1.2.3.4\n * www.example.com IN CNAME a.example.com.\n * a.example.com IN A 5.6.7.8\n * then this would store the first A record, the CNAME, then the second A\n * record which would overwrite the first.\n *\n * @param node the namehash of the node for which to set the records\n * @param data the DNS wire format records to set\n */\n function setDNSRecords(\n bytes32 node,\n bytes calldata data\n ) external virtual authorised(node) {\n uint16 resource = 0;\n uint256 offset = 0;\n bytes memory name;\n bytes memory value;\n bytes32 nameHash;\n uint64 version = recordVersions[node];\n // Iterate over the data to add the resource records\n for (\n RRUtils.RRIterator memory iter = data.iterateRRs(0);\n !iter.done();\n iter.next()\n ) {\n if (resource == 0) {\n resource = iter.dnstype;\n name = iter.name();\n nameHash = keccak256(abi.encodePacked(name));\n value = bytes(iter.rdata());\n } else {\n bytes memory newName = iter.name();\n if (resource != iter.dnstype || !name.equals(newName)) {\n setDNSRRSet(\n node,\n name,\n resource,\n data,\n offset,\n iter.offset - offset,\n value.length == 0,\n version\n );\n resource = iter.dnstype;\n offset = iter.offset;\n name = newName;\n nameHash = keccak256(name);\n value = bytes(iter.rdata());\n }\n }\n }\n if (name.length > 0) {\n setDNSRRSet(\n node,\n name,\n resource,\n data,\n offset,\n data.length - offset,\n value.length == 0,\n version\n );\n }\n }\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 ) public view virtual override returns (bytes memory) {\n return versionable_records[recordVersions[node]][node][name][resource];\n }\n\n /**\n * Check if a given node has records.\n * @param node the namehash of the node for which to check the records\n * @param name the namehash of the node for which to check the records\n */\n function hasDNSRecords(\n bytes32 node,\n bytes32 name\n ) public view virtual returns (bool) {\n return (versionable_nameEntriesCount[recordVersions[node]][node][\n name\n ] != 0);\n }\n\n /**\n * setZonehash sets the hash for the zone.\n * May only be called by the owner of that node in the ENS registry.\n * @param node The node to update.\n * @param hash The zonehash to set\n */\n function setZonehash(\n bytes32 node,\n bytes calldata hash\n ) external virtual authorised(node) {\n uint64 currentRecordVersion = recordVersions[node];\n bytes memory oldhash = versionable_zonehashes[currentRecordVersion][\n node\n ];\n versionable_zonehashes[currentRecordVersion][node] = hash;\n emit DNSZonehashChanged(node, oldhash, hash);\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(\n bytes32 node\n ) external view virtual override returns (bytes memory) {\n return versionable_zonehashes[recordVersions[node]][node];\n }\n\n function supportsInterface(\n bytes4 interfaceID\n ) public view virtual override returns (bool) {\n return\n interfaceID == type(IDNSRecordResolver).interfaceId ||\n interfaceID == type(IDNSZoneResolver).interfaceId ||\n super.supportsInterface(interfaceID);\n }\n\n function setDNSRRSet(\n bytes32 node,\n bytes memory name,\n uint16 resource,\n bytes memory data,\n uint256 offset,\n uint256 size,\n bool deleteRecord,\n uint64 version\n ) private {\n bytes32 nameHash = keccak256(name);\n bytes memory rrData = data.substring(offset, size);\n if (deleteRecord) {\n if (\n versionable_records[version][node][nameHash][resource].length !=\n 0\n ) {\n versionable_nameEntriesCount[version][node][nameHash]--;\n }\n delete (versionable_records[version][node][nameHash][resource]);\n emit DNSRecordDeleted(node, name, resource);\n } else {\n if (\n versionable_records[version][node][nameHash][resource].length ==\n 0\n ) {\n versionable_nameEntriesCount[version][node][nameHash]++;\n }\n versionable_records[version][node][nameHash][resource] = rrData;\n emit DNSRecordChanged(node, name, resource, rrData);\n }\n }\n}\n" + }, + "contracts/resolvers/profiles/ExtendedDNSResolver.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/utils/Strings.sol\";\nimport \"../../resolvers/profiles/IExtendedDNSResolver.sol\";\nimport \"../../resolvers/profiles/IAddressResolver.sol\";\nimport \"../../resolvers/profiles/IAddrResolver.sol\";\nimport \"../../resolvers/profiles/ITextResolver.sol\";\nimport \"../../utils/HexUtils.sol\";\nimport \"../../utils/BytesUtils.sol\";\n\n/**\n * @dev Resolves names on ENS by interpreting record data stored in a DNS TXT record.\n * This resolver implements the IExtendedDNSResolver interface, meaning that when\n * a DNS name specifies it as the resolver via a TXT record, this resolver's\n * resolve() method is invoked, and is passed any additional information from that\n * text record. This resolver implements a simple text parser allowing a variety\n * of records to be specified in text, which will then be used to resolve the name\n * in ENS.\n *\n * To use this, set a TXT record on your DNS name in the following format:\n * ENS1