creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "mainnet/0x9AcF316290AaA62edafdDDaC48B124032C36EB3c/contracts/OffChainResolver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./IExtendedResolver.sol\";\nimport \"./SignatureVerifier.sol\";\nimport \"./SupportsInterface.sol\";\n\n/**\n* Interface for the resolver service.\n*/\ninterface IResolverService {\n    function resolve(bytes calldata name, bytes calldata data) external view returns(bytes memory result, uint64 expires, bytes memory sig);\n}\n\n/**\n * Implements an ENS resolver that directs all queries to a CCIP read gateway.\n * Callers must implement EIP 3668 and ENSIP 10.\n */\ncontract OffchainResolver is IExtendedResolver, Ownable, SupportsInterface {\n\n    /**\n    * The URL to call for offchain resolution.\n    */\n    string public url;\n    /**\n    * The addresses that are allowed to sign responses.\n    */\n    mapping(address=>bool) public signers;\n    /**\n    * The environment of the resolver. 0 for production - 1 for development. Others might be identified in the future.\n    */\n    uint public ENV;\n\n    /**\n    * Emitted when a new signers are added.\n    */\n    event NewSigners(address[] signers);\n    /**\n    * Emitted when a signer is removed.\n    */\n    event RemovedSigner(address signers);\n    /**\n    * Emitted when an offchain lookup is performed.\n    */\n    error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData);\n\n    /**\n    * @dev Constructor\n    * @param _url The URL to call\n    * @param _signers The addresses that are allowed to sign responses\n    * @param _env The env of the resolver. 0 for production - 1 for development. Others might be identified in the\n    future.\n    */\n    constructor(string memory _url, address[] memory _signers, uint _env) Ownable(msg.sender) {\n        url = _url;\n        for(uint i = 0; i < _signers.length; i++) {\n            signers[_signers[i]] = true;\n        }\n        ENV = _env;\n        emit NewSigners(_signers);\n    }\n\n    /**\n    * Generates a hash for signing/verifying.\n    * @param target: The address the signature is for.\n    * @param expires: The expiration time of the signature.\n    * @param request: The original request that was sent.\n    * @param result: The `result` field of the response (not including the signature part).\n    */\n    function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) external pure returns(bytes32) {\n        return SignatureVerifier.makeSignatureHash(target, expires, request, result);\n    }\n\n    /**\n     * Resolves a name, as specified by ENSIP 10.\n     * @param name The DNS-encoded name to resolve.\n     * @param data The ABI encoded data for the underlying resolution function (Eg, addr(bytes32), text(bytes32,string), etc).\n     * @return The return data, ABI encoded identically to the underlying function.\n     */\n    function resolve(bytes calldata name, bytes calldata data) external override view returns(bytes memory) {\n        bytes memory callData = abi.encodeWithSelector(IResolverService.resolve.selector, name, data);\n        string[] memory urls = new string[](1);\n        urls[0] = url;\n        revert OffchainLookup(\n            address(this),\n            urls,\n            callData,\n            OffchainResolver.resolveWithProof.selector,\n            callData\n        );\n    }\n\n    /**\n     * Callback used by CCIP read compatible clients to verify and parse the response.\n     */\n    function resolveWithProof(bytes calldata response, bytes calldata extraData) external view returns(bytes memory) {\n        (address signer, bytes memory result) = SignatureVerifier.verify(extraData, response);\n        require(\n            signers[signer],\n            \"SignatureVerifier: Invalid sigature\");\n        return result;\n    }\n\n    /**\n    * Returns true if the resolver supports the specified interface.\n    * @param interfaceID The ID of the interface to check for.\n    * @return True if the contract implements `interfaceID`, false otherwise.\n    */\n    function supportsInterface(bytes4 interfaceID) public pure override returns(bool) {\n        return interfaceID == type(IExtendedResolver).interfaceId || super.supportsInterface(interfaceID);\n    }\n\n    /**\n     * Sets the URL to call.\n     * Only the owner can call this function.\n     * @param _url The URL to call.\n     */\n    function setUrl(string calldata _url) external onlyOwner {\n        url = _url;\n    }\n\n    /**\n     * Sets the signers for the resolver service.\n     * Only the owner can call this function.\n     * @param _signers The signers to add.\n     */\n    function setSigners(address[] calldata _signers) external onlyOwner {\n        for(uint i = 0; i < _signers.length; i++) {\n            signers[_signers[i]] = true;\n        }\n        emit NewSigners(_signers);\n    }\n\n    /**\n     * Removes signers for the resolver service.\n     * Only the owner can call this function.\n     * @param _signer The signer to remove.\n     */\n    function removeSigner(address _signer) external onlyOwner {\n        signers[_signer] = false;\n        emit RemovedSigner(_signer);\n    }\n\n}\n"
      },
      "mainnet/0x9AcF316290AaA62edafdDDaC48B124032C36EB3c/contracts/SupportsInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\nimport \"./ISupportsInterface.sol\";\n\nabstract contract SupportsInterface is ISupportsInterface {\n    function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) {\n        return interfaceID == type(ISupportsInterface).interfaceId;\n    }\n}\n"
      },
      "mainnet/0x9AcF316290AaA62edafdDDaC48B124032C36EB3c/contracts/SignatureVerifier.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.20;\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n\nlibrary SignatureVerifier {\n    /**\n     * @dev Generates a hash for signing/verifying.\n     * @param target: The address the signature is for.\n     * @param request: The original request that was sent.\n     * @param result: The `result` field of the response (not including the signature part).\n     */\n    function makeSignatureHash(address target, uint64 expires, bytes memory request, bytes memory result) internal pure returns(bytes32) {\n        return keccak256(abi.encodePacked(hex\"1900\", target, expires, keccak256(request), keccak256(result)));\n    }\n\n    /**\n     * @dev Verifies a signed message returned from a callback.\n     * @param request: The original request that was sent.\n     * @param response: An ABI encoded tuple of `(bytes result, uint64 expires, bytes sig)`, where `result` is the data to return\n     *        to the caller, and `sig` is the (r,s,v) encoded message signature.\n     * @return signer: The address that signed this message.\n     * @return result: The `result` decoded from `response`.\n     */\n    function verify(bytes calldata request, bytes calldata response) internal view returns(address, bytes memory) {\n        (bytes memory result, uint64 expires, bytes memory sig) = abi.decode(response, (bytes, uint64, bytes));\n        address signer = ECDSA.recover(makeSignatureHash(address(this), expires, request, result), sig);\n        require(\n            expires >= block.timestamp,\n            \"SignatureVerifier: Signature expired\");\n        return (signer, result);\n    }\n}"
      },
      "mainnet/0x9AcF316290AaA62edafdDDaC48B124032C36EB3c/contracts/IExtendedResolver.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IExtendedResolver {\n    function resolve(bytes memory name, bytes memory data) external view returns(bytes memory);\n}"
      },
      "@openzeppelin/contracts/access/Ownable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../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 * The initial owner is set to the address provided by the deployer. This can\n * 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    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\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        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\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        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\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"
      },
      "mainnet/0x9AcF316290AaA62edafdDDaC48B124032C36EB3c/contracts/ISupportsInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface ISupportsInterface {\n    function supportsInterface(bytes4 interfaceID) external pure returns(bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\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    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile 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 {MessageHashUtils-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    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\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, bytes32(signature.length));\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 precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\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    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\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    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError, bytes32) {\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, s);\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, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\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, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\n     */\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\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    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": false,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "abi"
          ]
        }
      },
      "remappings": []
    }
  }}