{"compiler":{"version":"0.8.25+commit.b61c2a91"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"admin_","type":"address"},{"internalType":"address","name":"implementation_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerNotAdmin","type":"error"},{"inputs":[],"name":"InvalidImplementation","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"inputs":[],"name":"SameImplementation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"details":"A specialized proxy for UniversalResolver that forwards method calls and properly handles CCIP-Read reverts. Admin can upgrade the implementation.","errors":{"OffchainLookup(address,string[],bytes,bytes4,bytes)":[{"details":"https://eips.ethereum.org/EIPS/eip-3668 Error selector: `0x556f1830`"}]},"kind":"dev","methods":{"admin()":{"details":"Returns the current admin address."},"constructor":{"details":"Initializes the proxy with an implementation and admin."},"implementation()":{"details":"Returns the current implementation address."},"renounceAdmin()":{"details":"Allows admin to revoke their admin rights by setting admin to address(0)."},"upgradeTo(address)":{"details":"Upgrades to a new implementation.","params":{"newImplementation":"Address of the new implementation"}}},"title":"UpgradableUniversalResolverProxy","version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"src/universalResolver/UpgradableUniversalResolverProxy.sol":"UpgradableUniversalResolverProxy"},"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs","useLiteralContent":true},"optimizer":{"enabled":true,"runs":1000},"remappings":[":@ens/contracts/=lib/ens-contracts/contracts/",":@ensdomains/buffer/=lib/buffer/",":@ensdomains/verifiable-factory/=lib/verifiable-factory/src/",":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",":@unruggable/gateways/=lib/unruggable-gateways/",":forge-std/=lib/forge-std/src/"]},"sources":{"lib/ens-contracts/contracts/ccipRead/EIP3668.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @dev https://eips.ethereum.org/EIPS/eip-3668\n/// Error selector: `0x556f1830`\nerror OffchainLookup(\n    address sender,\n    string[] urls,\n    bytes callData,\n    bytes4 callbackFunction,\n    bytes extraData\n);\n\n/// @dev Simple library for decoding `OffchainLookup` error data.\n/// Avoids \"stack too deep\" issues as the natural decoding consumes 5 variables.\nlibrary EIP3668 {\n    /// @dev Struct with members matching `OffchainLookup`.\n    struct Params {\n        address sender;\n        string[] urls;\n        bytes callData;\n        bytes4 callbackFunction;\n        bytes extraData;\n    }\n\n    /// @dev Decode an `OffchainLookup` into a struct from the data after the error selector.\n    function decode(bytes memory v) internal pure returns (Params memory p) {\n        (p.sender, p.urls, p.callData, p.callbackFunction, p.extraData) = abi\n            .decode(v, (address, string[], bytes, bytes4, bytes));\n    }\n}\n","keccak256":"0x14619de0f3d9f085e6209767b35c2888b8d2af6d787af535f30db7b51e843bf8","license":"MIT"},"lib/ens-contracts/contracts/utils/BytesUtils.sol":{"content":"//SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\nlibrary BytesUtils {\n    error OffsetOutOfBoundsError(uint256 offset, uint256 length);\n\n    /// @dev Returns the keccak-256 hash of a byte range.\n    /// @param self The byte string to hash.\n    /// @param offset The position to start hashing at.\n    /// @param len The number of bytes to hash.\n    /// @return ret The hash of the byte range.\n    function keccak(\n        bytes memory self,\n        uint256 offset,\n        uint256 len\n    ) internal pure returns (bytes32 ret) {\n        require(offset + len <= self.length);\n        assembly {\n            ret := keccak256(add(add(self, 32), offset), len)\n        }\n    }\n\n    /// @dev Returns a positive number if `other` comes lexicographically after\n    ///      `self`, a negative number if it comes before, or zero if the\n    ///      contents of the two bytes are equal.\n    /// @param self The first bytes to compare.\n    /// @param other The second bytes to compare.\n    /// @return The result of the comparison.\n    function compare(\n        bytes memory self,\n        bytes memory other\n    ) internal pure returns (int256) {\n        return compare(self, 0, self.length, other, 0, other.length);\n    }\n\n    /// @dev Returns a positive number if `other` comes lexicographically after\n    ///      `self`, a negative number if it comes before, or zero if the\n    ///      contents of the two bytes are equal. Comparison is done per-rune,\n    ///      on unicode codepoints.\n    /// @param self The first bytes to compare.\n    /// @param offset The offset of self.\n    /// @param len    The length of self.\n    /// @param other The second bytes to compare.\n    /// @param otheroffset The offset of the other string.\n    /// @param otherlen    The length of the other string.\n    /// @return The result of the comparison.\n    function compare(\n        bytes memory self,\n        uint256 offset,\n        uint256 len,\n        bytes memory other,\n        uint256 otheroffset,\n        uint256 otherlen\n    ) internal pure returns (int256) {\n        if (offset + len > self.length) {\n            revert OffsetOutOfBoundsError(offset + len, self.length);\n        }\n        if (otheroffset + otherlen > other.length) {\n            revert OffsetOutOfBoundsError(otheroffset + otherlen, other.length);\n        }\n\n        uint256 shortest = len;\n        if (otherlen < len) shortest = otherlen;\n\n        uint256 selfptr;\n        uint256 otherptr;\n\n        assembly {\n            selfptr := add(self, add(offset, 32))\n            otherptr := add(other, add(otheroffset, 32))\n        }\n        for (uint256 idx = 0; idx < shortest; idx += 32) {\n            uint256 a;\n            uint256 b;\n            assembly {\n                a := mload(selfptr)\n                b := mload(otherptr)\n            }\n            if (a != b) {\n                uint256 rest = shortest - idx;\n                if (rest < 32) {\n                    // shift out the irrelevant bits\n                    rest = (32 - rest) << 3; // bits to drop\n                    a >>= rest;\n                    b >>= rest;\n                }\n                if (a < b) {\n                    return -1;\n                } else if (a > b) {\n                    return 1;\n                }\n            }\n            selfptr += 32;\n            otherptr += 32;\n        }\n\n        return int256(len) - int256(otherlen);\n    }\n\n    /// @dev Returns true if the two byte ranges are equal.\n    /// @param self The first byte range to compare.\n    /// @param offset The offset into the first byte range.\n    /// @param other The second byte range to compare.\n    /// @param otherOffset The offset into the second byte range.\n    /// @param len The number of bytes to compare\n    /// @return True if the byte ranges are equal, false otherwise.\n    function equals(\n        bytes memory self,\n        uint256 offset,\n        bytes memory other,\n        uint256 otherOffset,\n        uint256 len\n    ) internal pure returns (bool) {\n        return keccak(self, offset, len) == keccak(other, otherOffset, len);\n    }\n\n    /// @dev Returns true if the two byte ranges are equal with offsets.\n    /// @param self The first byte range to compare.\n    /// @param offset The offset into the first byte range.\n    /// @param other The second byte range to compare.\n    /// @param otherOffset The offset into the second byte range.\n    /// @return True if the byte ranges are equal, false otherwise.\n    function equals(\n        bytes memory self,\n        uint256 offset,\n        bytes memory other,\n        uint256 otherOffset\n    ) internal pure returns (bool) {\n        return\n            keccak(self, offset, self.length - offset) ==\n            keccak(other, otherOffset, other.length - otherOffset);\n    }\n\n    /// @dev Compares a range of 'self' to all of 'other' and returns True iff\n    ///      they are equal.\n    /// @param self The first byte range to compare.\n    /// @param offset The offset into the first byte range.\n    /// @param other The second byte range to compare.\n    /// @return True if the byte ranges are equal, false otherwise.\n    function equals(\n        bytes memory self,\n        uint256 offset,\n        bytes memory other\n    ) internal pure returns (bool) {\n        return\n            self.length == offset + other.length &&\n            equals(self, offset, other, 0, other.length);\n    }\n\n    /// @dev Returns true if the two byte ranges are equal.\n    /// @param self The first byte range to compare.\n    /// @param other The second byte range to compare.\n    /// @return True if the byte ranges are equal, false otherwise.\n    function equals(\n        bytes memory self,\n        bytes memory other\n    ) internal pure returns (bool) {\n        return\n            self.length == other.length &&\n            equals(self, 0, other, 0, self.length);\n    }\n\n    /// @dev Returns the 8-bit number at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes\n    /// @return ret The specified 8 bits of the string, interpreted as an integer.\n    function readUint8(\n        bytes memory self,\n        uint256 idx\n    ) internal pure returns (uint8 ret) {\n        return uint8(self[idx]);\n    }\n\n    /// @dev Returns the 16-bit number at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes\n    /// @return ret The specified 16 bits of the string, interpreted as an integer.\n    function readUint16(\n        bytes memory self,\n        uint256 idx\n    ) internal pure returns (uint16 ret) {\n        require(idx + 2 <= self.length);\n        assembly {\n            ret := and(mload(add(add(self, 2), idx)), 0xFFFF)\n        }\n    }\n\n    /// @dev Returns the 32-bit number at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes\n    /// @return ret The specified 32 bits of the string, interpreted as an integer.\n    function readUint32(\n        bytes memory self,\n        uint256 idx\n    ) internal pure returns (uint32 ret) {\n        require(idx + 4 <= self.length);\n        assembly {\n            ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF)\n        }\n    }\n\n    /// @dev Returns the 32 byte value at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes\n    /// @return ret The specified 32 bytes of the string.\n    function readBytes32(\n        bytes memory self,\n        uint256 idx\n    ) internal pure returns (bytes32 ret) {\n        require(idx + 32 <= self.length);\n        assembly {\n            ret := mload(add(add(self, 32), idx))\n        }\n    }\n\n    /// @dev Returns the 32 byte value at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes\n    /// @return ret The specified 32 bytes of the string.\n    function readBytes20(\n        bytes memory self,\n        uint256 idx\n    ) internal pure returns (bytes20 ret) {\n        require(idx + 20 <= self.length);\n        assembly {\n            ret := and(\n                mload(add(add(self, 32), idx)),\n                0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000\n            )\n        }\n    }\n\n    /// @dev Returns the n byte value at the specified index of self.\n    /// @param self The byte string.\n    /// @param idx The index into the bytes.\n    /// @param len The number of bytes.\n    /// @return ret The specified 32 bytes of the string.\n    function readBytesN(\n        bytes memory self,\n        uint256 idx,\n        uint256 len\n    ) internal pure returns (bytes32 ret) {\n        require(len <= 32);\n        require(idx + len <= self.length);\n        assembly {\n            let mask := not(sub(exp(256, sub(32, len)), 1))\n            ret := and(mload(add(add(self, 32), idx)), mask)\n        }\n    }\n\n    function memcpy(uint256 dest, uint256 src, uint256 len) private pure {\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            uint256 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\n    /// @dev Copies a substring into a new byte string.\n    /// @param self The byte string to copy from.\n    /// @param offset The offset to start copying at.\n    /// @param len The number of bytes to copy.\n    function substring(\n        bytes memory self,\n        uint256 offset,\n        uint256 len\n    ) internal pure returns (bytes memory) {\n        require(offset + len <= self.length);\n\n        bytes memory ret = new bytes(len);\n        uint256 dest;\n        uint256 src;\n\n        assembly {\n            dest := add(ret, 32)\n            src := add(add(self, 32), offset)\n        }\n        memcpy(dest, src, len);\n\n        return ret;\n    }\n\n    // Maps characters from 0x30 to 0x7A to their base32 values.\n    // 0xFF represents invalid characters in that range.\n    bytes constant base32HexTable =\n        hex\"00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F\";\n\n    /// @dev Decodes unpadded base32 data of up to one word in length.\n    /// @param self The data to decode.\n    /// @param off Offset into the string to start at.\n    /// @param len Number of characters to decode.\n    /// @return The decoded data, left aligned.\n    function base32HexDecodeWord(\n        bytes memory self,\n        uint256 off,\n        uint256 len\n    ) internal pure returns (bytes32) {\n        require(len <= 52);\n\n        uint256 ret = 0;\n        uint8 decoded;\n        for (uint256 i = 0; i < len; i++) {\n            bytes1 char = self[off + i];\n            require(char >= 0x30 && char <= 0x7A);\n            decoded = uint8(base32HexTable[uint256(uint8(char)) - 0x30]);\n            require(decoded <= 0x20);\n            if (i == len - 1) {\n                break;\n            }\n            ret = (ret << 5) | decoded;\n        }\n\n        uint256 bitlen = len * 5;\n        if (len % 8 == 0) {\n            // Multiple of 8 characters, no padding\n            ret = (ret << 5) | decoded;\n        } else if (len % 8 == 2) {\n            // Two extra characters - 1 byte\n            ret = (ret << 3) | (decoded >> 2);\n            bitlen -= 2;\n        } else if (len % 8 == 4) {\n            // Four extra characters - 2 bytes\n            ret = (ret << 1) | (decoded >> 4);\n            bitlen -= 4;\n        } else if (len % 8 == 5) {\n            // Five extra characters - 3 bytes\n            ret = (ret << 4) | (decoded >> 1);\n            bitlen -= 1;\n        } else if (len % 8 == 7) {\n            // Seven extra characters - 4 bytes\n            ret = (ret << 2) | (decoded >> 3);\n            bitlen -= 3;\n        } else {\n            revert();\n        }\n\n        return bytes32(ret << (256 - bitlen));\n    }\n\n    /// @dev Finds the first occurrence of the byte `needle` in `self`.\n    /// @param self The string to search\n    /// @param off The offset to start searching at\n    /// @param len The number of bytes to search\n    /// @param needle The byte to search for\n    /// @return The offset of `needle` in `self`, or 2**256-1 if it was not found.\n    function find(\n        bytes memory self,\n        uint256 off,\n        uint256 len,\n        bytes1 needle\n    ) internal pure returns (uint256) {\n        for (uint256 idx = off; idx < off + len; idx++) {\n            if (self[idx] == needle) {\n                return idx;\n            }\n        }\n        return type(uint256).max;\n    }\n}\n","keccak256":"0x91aa93c6538538518436746a72ed262b677c5216209b7a7f32dbf5f87018ba52","license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n\n        (bool success, bytes memory returndata) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            _revert(returndata);\n        }\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 or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\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    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\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    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n     */\n    function _revert(bytes memory returndata) 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            assembly (\"memory-safe\") {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n","keccak256":"0xaaa1d17c1129b127a4a401db2fbd72960e2671474be3d08cae71ccdc42f7624c","license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/Errors.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n","keccak256":"0x6afa713bfd42cf0f7656efa91201007ac465e42049d7de1d50753a373648c123","license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n","keccak256":"0xcf74f855663ce2ae00ed8352666b7935f6cddea2932fdf2c3ecd30a9b1cd0e97","license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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":"0x79796192ec90263f21b464d5bc90b777a525971d3de8232be80d9c4f9fb353b8","license":"MIT"},"src/universalResolver/UpgradableUniversalResolverProxy.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport \"@openzeppelin/contracts/utils/StorageSlot.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n// CCIP-Read Imports\nimport {EIP3668, OffchainLookup} from \"@ens/contracts/ccipRead/EIP3668.sol\";\nimport {BytesUtils} from \"@ens/contracts/utils/BytesUtils.sol\";\n\n/**\n * @title UpgradableUniversalResolverProxy\n * @dev A specialized proxy for UniversalResolver that forwards method calls\n * and properly handles CCIP-Read reverts. Admin can upgrade the implementation.\n */\ncontract UpgradableUniversalResolverProxy {\n    // Storage slot for implementation address (EIP-1967 compatible)\n    bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    // Storage slot for admin (EIP-1967 compatible)\n    bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    // Custom errors\n    error CallerNotAdmin();\n    error InvalidImplementation();\n    error SameImplementation();\n\n    // Events\n    event Upgraded(address indexed implementation);\n    event AdminChanged(address indexed previousAdmin, address indexed newAdmin);\n    event AdminRemoved(address indexed admin);\n\n    /**\n     * @dev Initializes the proxy with an implementation and admin.\n     */\n    constructor(address admin_, address implementation_) {\n        _validateImplementation(implementation_);\n        _setImplementation(implementation_);\n        _setAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier restricting a function to the admin.\n     */\n    modifier onlyAdmin() {\n        if (msg.sender != _getAdmin()) revert CallerNotAdmin();\n        _;\n    }\n\n    // --- Admin Functions ---\n\n    /**\n     * @dev Upgrades to a new implementation.\n     * @param newImplementation Address of the new implementation\n     */\n    function upgradeTo(address newImplementation) external onlyAdmin {\n        _validateImplementation(newImplementation);\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Allows admin to revoke their admin rights by setting admin to address(0).\n     */\n    function renounceAdmin() external onlyAdmin {\n        address admin_ = _getAdmin();\n        _setAdmin(address(0));\n        emit AdminRemoved(admin_);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function implementation() external view returns (address) {\n        return _getImplementation();\n    }\n\n    /**\n     * @dev Returns the current admin address.\n     */\n    function admin() external view returns (address) {\n        return _getAdmin();\n    }\n\n    // --- Internal Admin/Implementation Logic ---\n\n    /**\n     * @dev Validates if the implementation is valid.\n     */\n    function _validateImplementation(address newImplementation) internal view {\n        if (newImplementation == address(0) || newImplementation.code.length == 0) {\n            revert InvalidImplementation();\n        }\n        if (_getImplementation() == newImplementation) {\n            revert SameImplementation();\n        }\n    }\n\n    /**\n     * @dev Sets the implementation address in storage.\n     */\n    function _setImplementation(address newImplementation) private {\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Gets the current implementation address from storage.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Sets the admin address in storage.\n     */\n    function _setAdmin(address newAdmin) private {\n        address previousAdmin = _getAdmin();\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n        emit AdminChanged(previousAdmin, newAdmin);\n    }\n\n    /**\n     * @dev Gets the current admin address from storage.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    // --- Fallback ---\n\n    /**\n     * @dev Fallback function that handles forwarding calls to the implementation\n     * and properly manages CCIP-Read reverts.\n     */\n    fallback() external {\n        (bool ok, bytes memory v) = _getImplementation().staticcall(msg.data);\n        if (!ok && bytes4(v) == OffchainLookup.selector) {\n            EIP3668.Params memory p = EIP3668.decode(BytesUtils.substring(v, 4, v.length - 4));\n            if (p.sender == _getImplementation()) {\n                revert OffchainLookup(address(this), p.urls, p.callData, p.callbackFunction, p.extraData);\n            }\n        }\n\n        if (ok) {\n            assembly {\n                return(add(v, 32), mload(v))\n            }\n        } else {\n            assembly {\n                revert(add(v, 32), mload(v))\n            }\n        }\n    }\n}\n","keccak256":"0xdfd947faffc751e238fcc6c9ddf82d1a6f673ee33614be797b96ad37ecdc5781","license":"MIT"}},"version":1}