creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/eip/ERC1271.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.0;\n\nabstract contract ERC1271 {\n    // bytes4(keccak256(\"isValidSignature(bytes32,bytes)\")\n    bytes4 internal constant MAGICVALUE = 0x1626ba7e;\n\n    /**\n     * @dev Should return whether the signature provided is valid for the provided hash\n     * @param _hash      Hash of the data to be signed\n     * @param _signature Signature byte array associated with _hash\n     *\n     * MUST return the bytes4 magic value 0x1626ba7e when function passes.\n     * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n     * MUST allow external calls\n     */\n    function isValidSignature(bytes32 _hash, bytes memory _signature) public view virtual returns (bytes4 magicValue);\n}\n"
      },
      "contracts/eip/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 \"./interface/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"
      },
      "contracts/eip/interface/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 * [EIP](https://eips.ethereum.org/EIPS/eip-165).\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     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "contracts/extension/Multicall.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../lib/Address.sol\";\nimport \"./interface/IMulticall.sol\";\n\n/**\n * @dev Provides a function to batch together multiple calls in a single external call.\n *\n * _Available since v4.1._\n */\ncontract Multicall is IMulticall {\n    /**\n     *  @notice Receives and executes a batch of function calls on this contract.\n     *  @dev Receives and executes a batch of function calls on this contract.\n     *\n     *  @param data The bytes data that makes up the batch of function calls to execute.\n     *  @return results The bytes data that makes up the result of the batch of function calls executed.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results) {\n        results = new bytes[](data.length);\n        address sender = _msgSender();\n        bool isForwarder = msg.sender != sender;\n        for (uint256 i = 0; i < data.length; i++) {\n            if (isForwarder) {\n                results[i] = Address.functionDelegateCall(address(this), abi.encodePacked(data[i], sender));\n            } else {\n                results[i] = Address.functionDelegateCall(address(this), data[i]);\n            }\n        }\n        return results;\n    }\n\n    /// @notice Returns the sender in the given execution context.\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n}\n"
      },
      "contracts/extension/interface/IAccountPermissions.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\ninterface IAccountPermissions {\n    /*///////////////////////////////////////////////////////////////\n                                Types\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice The payload that must be signed by an authorized wallet to set permissions for a signer to use the smart wallet.\n     *\n     *  @param signer The addres of the signer to give permissions.\n     *  @param approvedTargets The list of approved targets that a role holder can call using the smart wallet.\n     *  @param nativeTokenLimitPerTransaction The maximum value that can be transferred by a role holder in a single transaction.\n     *  @param permissionStartTimestamp The UNIX timestamp at and after which a signer has permission to use the smart wallet.\n     *  @param permissionEndTimestamp The UNIX timestamp at and after which a signer no longer has permission to use the smart wallet.\n     *  @param reqValidityStartTimestamp The UNIX timestamp at and after which a signature is valid.\n     *  @param reqValidityEndTimestamp The UNIX timestamp at and after which a signature is invalid/expired.\n     *  @param uid A unique non-repeatable ID for the payload.\n     *  @param isAdmin Whether the signer should be an admin.\n     */\n    struct SignerPermissionRequest {\n        address signer;\n        uint8 isAdmin;\n        address[] approvedTargets;\n        uint256 nativeTokenLimitPerTransaction;\n        uint128 permissionStartTimestamp;\n        uint128 permissionEndTimestamp;\n        uint128 reqValidityStartTimestamp;\n        uint128 reqValidityEndTimestamp;\n        bytes32 uid;\n    }\n\n    /**\n     *  @notice The permissions that a signer has to use the smart wallet.\n     *\n     *  @param signer The address of the signer.\n     *  @param approvedTargets The list of approved targets that a role holder can call using the smart wallet.\n     *  @param nativeTokenLimitPerTransaction The maximum value that can be transferred by a role holder in a single transaction.\n     *  @param startTimestamp The UNIX timestamp at and after which a signer has permission to use the smart wallet.\n     *  @param endTimestamp The UNIX timestamp at and after which a signer no longer has permission to use the smart wallet.\n     */\n    struct SignerPermissions {\n        address signer;\n        address[] approvedTargets;\n        uint256 nativeTokenLimitPerTransaction;\n        uint128 startTimestamp;\n        uint128 endTimestamp;\n    }\n\n    /**\n     *  @notice Internal struct for storing permissions for a signer (without approved targets).\n     *\n     *  @param nativeTokenLimitPerTransaction The maximum value that can be transferred by a role holder in a single transaction.\n     *  @param startTimestamp The UNIX timestamp at and after which a signer has permission to use the smart wallet.\n     *  @param endTimestamp The UNIX timestamp at and after which a signer no longer has permission to use the smart wallet.\n     */\n    struct SignerPermissionsStatic {\n        uint256 nativeTokenLimitPerTransaction;\n        uint128 startTimestamp;\n        uint128 endTimestamp;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                                Events\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Emitted when permissions for a signer are updated.\n    event SignerPermissionsUpdated(\n        address indexed authorizingSigner,\n        address indexed targetSigner,\n        SignerPermissionRequest permissions\n    );\n\n    /// @notice Emitted when an admin is set or removed.\n    event AdminUpdated(address indexed signer, bool isAdmin);\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns whether the given account is an admin.\n    function isAdmin(address signer) external view returns (bool);\n\n    /// @notice Returns whether the given account is an active signer on the account.\n    function isActiveSigner(address signer) external view returns (bool);\n\n    /// @notice Returns the restrictions under which a signer can use the smart wallet.\n    function getPermissionsForSigner(address signer) external view returns (SignerPermissions memory permissions);\n\n    /// @notice Returns all active and inactive signers of the account.\n    function getAllSigners() external view returns (SignerPermissions[] memory signers);\n\n    /// @notice Returns all signers with active permissions to use the account.\n    function getAllActiveSigners() external view returns (SignerPermissions[] memory signers);\n\n    /// @notice Returns all admins of the account.\n    function getAllAdmins() external view returns (address[] memory admins);\n\n    /// @dev Verifies that a request is signed by an authorized account.\n    function verifySignerPermissionRequest(\n        SignerPermissionRequest calldata req,\n        bytes calldata signature\n    ) external view returns (bool success, address signer);\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Sets the permissions for a given signer.\n    function setPermissionsForSigner(SignerPermissionRequest calldata req, bytes calldata signature) external;\n}\n"
      },
      "contracts/extension/interface/IContractMetadata.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n *  Thirdweb's `ContractMetadata` is a contract extension for any base contracts. It lets you set a metadata URI\n *  for you contract.\n *\n *  Additionally, `ContractMetadata` is necessary for NFT contracts that want royalties to get distributed on OpenSea.\n */\n\ninterface IContractMetadata {\n    /// @dev Returns the metadata URI of the contract.\n    function contractURI() external view returns (string memory);\n\n    /**\n     *  @dev Sets contract URI for the storefront-level metadata of the contract.\n     *       Only module admin can call this function.\n     */\n    function setContractURI(string calldata _uri) external;\n\n    /// @dev Emitted when the contract URI is updated.\n    event ContractURIUpdated(string prevURI, string newURI);\n}\n"
      },
      "contracts/extension/interface/IMulticall.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n * @dev Provides a function to batch together multiple calls in a single external call.\n *\n * _Available since v4.1._\n */\ninterface IMulticall {\n    /**\n     * @dev Receives and executes a batch of function calls on this contract.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results);\n}\n"
      },
      "contracts/extension/interface/IPermissions.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IPermissions {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
      },
      "contracts/extension/interface/IPermissionsEnumerable.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"./IPermissions.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IPermissionsEnumerable is IPermissions {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * [forum post](https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296)\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"
      },
      "contracts/extension/upgradeable/AccountPermissions.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../interface/IAccountPermissions.sol\";\nimport \"../../external-deps/openzeppelin/utils/cryptography/EIP712.sol\";\nimport \"../../external-deps/openzeppelin/utils/structs/EnumerableSet.sol\";\n\nlibrary AccountPermissionsStorage {\n    /// @custom:storage-location erc7201:account.permissions.storage\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"account.permissions.storage\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 public constant ACCOUNT_PERMISSIONS_STORAGE_POSITION =\n        0x3181e78fc1b109bc611fd2406150bf06e33faa75f71cba12c3e1fd670f2def00;\n\n    struct Data {\n        /// @dev The set of all admins of the wallet.\n        EnumerableSet.AddressSet allAdmins;\n        /// @dev The set of all signers with permission to use the account.\n        EnumerableSet.AddressSet allSigners;\n        /// @dev Map from address => whether the address is an admin.\n        mapping(address => bool) isAdmin;\n        /// @dev Map from signer address => active restrictions for that signer.\n        mapping(address => IAccountPermissions.SignerPermissionsStatic) signerPermissions;\n        /// @dev Map from signer address => approved target the signer can call using the account contract.\n        mapping(address => EnumerableSet.AddressSet) approvedTargets;\n        /// @dev Mapping from a signed request UID => whether the request is processed.\n        mapping(bytes32 => bool) executed;\n    }\n\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = ACCOUNT_PERMISSIONS_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}\n\nabstract contract AccountPermissions is IAccountPermissions, EIP712 {\n    using ECDSA for bytes32;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    bytes32 private constant TYPEHASH =\n        keccak256(\n            \"SignerPermissionRequest(address signer,uint8 isAdmin,address[] approvedTargets,uint256 nativeTokenLimitPerTransaction,uint128 permissionStartTimestamp,uint128 permissionEndTimestamp,uint128 reqValidityStartTimestamp,uint128 reqValidityEndTimestamp,bytes32 uid)\"\n        );\n\n    function _onlyAdmin() internal virtual {\n        require(isAdmin(msg.sender), \"!admin\");\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Sets the permissions for a given signer.\n    function setPermissionsForSigner(SignerPermissionRequest calldata _req, bytes calldata _signature) external {\n        address targetSigner = _req.signer;\n\n        require(\n            _req.reqValidityStartTimestamp <= block.timestamp && block.timestamp < _req.reqValidityEndTimestamp,\n            \"!period\"\n        );\n\n        (bool success, address signer) = verifySignerPermissionRequest(_req, _signature);\n        require(success, \"!sig\");\n\n        _accountPermissionsStorage().executed[_req.uid] = true;\n\n        //isAdmin > 0, set admin or remove admin\n        if (_req.isAdmin > 0) {\n            //isAdmin = 1, set admin\n            //isAdmin > 1, remove admin\n            bool _isAdmin = _req.isAdmin == 1;\n\n            _setAdmin(targetSigner, _isAdmin);\n            return;\n        }\n\n        require(!isAdmin(targetSigner), \"admin\");\n\n        _accountPermissionsStorage().allSigners.add(targetSigner);\n\n        _accountPermissionsStorage().signerPermissions[targetSigner] = SignerPermissionsStatic(\n            _req.nativeTokenLimitPerTransaction,\n            _req.permissionStartTimestamp,\n            _req.permissionEndTimestamp\n        );\n\n        address[] memory currentTargets = _accountPermissionsStorage().approvedTargets[targetSigner].values();\n        uint256 len = currentTargets.length;\n\n        for (uint256 i = 0; i < len; i += 1) {\n            _accountPermissionsStorage().approvedTargets[targetSigner].remove(currentTargets[i]);\n        }\n\n        len = _req.approvedTargets.length;\n        for (uint256 i = 0; i < len; i += 1) {\n            _accountPermissionsStorage().approvedTargets[targetSigner].add(_req.approvedTargets[i]);\n        }\n\n        _afterSignerPermissionsUpdate(_req);\n\n        emit SignerPermissionsUpdated(signer, targetSigner, _req);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns whether the given account is an admin.\n    function isAdmin(address _account) public view virtual returns (bool) {\n        return _accountPermissionsStorage().isAdmin[_account];\n    }\n\n    /// @notice Returns whether the given account is an active signer on the account.\n    function isActiveSigner(address signer) public view returns (bool) {\n        SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[signer];\n\n        return\n            permissions.startTimestamp <= block.timestamp &&\n            block.timestamp < permissions.endTimestamp &&\n            _accountPermissionsStorage().approvedTargets[signer].length() > 0;\n    }\n\n    /// @notice Returns the restrictions under which a signer can use the smart wallet.\n    function getPermissionsForSigner(address signer) external view returns (SignerPermissions memory) {\n        SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[signer];\n\n        return\n            SignerPermissions(\n                signer,\n                _accountPermissionsStorage().approvedTargets[signer].values(),\n                permissions.nativeTokenLimitPerTransaction,\n                permissions.startTimestamp,\n                permissions.endTimestamp\n            );\n    }\n\n    /// @dev Verifies that a request is signed by an authorized account.\n    function verifySignerPermissionRequest(\n        SignerPermissionRequest calldata req,\n        bytes calldata signature\n    ) public view virtual returns (bool success, address signer) {\n        signer = _recoverAddress(_encodeRequest(req), signature);\n        success = !_accountPermissionsStorage().executed[req.uid] && isAdmin(signer);\n    }\n\n    /// @notice Returns all active and inactive signers of the account.\n    function getAllSigners() external view returns (SignerPermissions[] memory signers) {\n        address[] memory allSigners = _accountPermissionsStorage().allSigners.values();\n\n        uint256 len = allSigners.length;\n        signers = new SignerPermissions[](len);\n        for (uint256 i = 0; i < len; i += 1) {\n            address signer = allSigners[i];\n            SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[signer];\n\n            signers[i] = SignerPermissions(\n                signer,\n                _accountPermissionsStorage().approvedTargets[signer].values(),\n                permissions.nativeTokenLimitPerTransaction,\n                permissions.startTimestamp,\n                permissions.endTimestamp\n            );\n        }\n    }\n\n    /// @notice Returns all signers with active permissions to use the account.\n    function getAllActiveSigners() external view returns (SignerPermissions[] memory signers) {\n        address[] memory allSigners = _accountPermissionsStorage().allSigners.values();\n\n        uint256 len = allSigners.length;\n        uint256 numOfActiveSigners = 0;\n\n        for (uint256 i = 0; i < len; i += 1) {\n            if (isActiveSigner(allSigners[i])) {\n                numOfActiveSigners++;\n            } else {\n                allSigners[i] = address(0);\n            }\n        }\n\n        signers = new SignerPermissions[](numOfActiveSigners);\n        uint256 index = 0;\n        for (uint256 i = 0; i < len; i += 1) {\n            if (allSigners[i] != address(0)) {\n                address signer = allSigners[i];\n                SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[signer];\n\n                signers[index++] = SignerPermissions(\n                    signer,\n                    _accountPermissionsStorage().approvedTargets[signer].values(),\n                    permissions.nativeTokenLimitPerTransaction,\n                    permissions.startTimestamp,\n                    permissions.endTimestamp\n                );\n            }\n        }\n    }\n\n    /// @notice Returns all admins of the account.\n    function getAllAdmins() external view returns (address[] memory) {\n        return _accountPermissionsStorage().allAdmins.values();\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                        Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Runs after every `changeRole` run.\n    function _afterSignerPermissionsUpdate(SignerPermissionRequest calldata _req) internal virtual;\n\n    /// @notice Makes the given account an admin.\n    function _setAdmin(address _account, bool _isAdmin) internal virtual {\n        _accountPermissionsStorage().isAdmin[_account] = _isAdmin;\n\n        if (_isAdmin) {\n            _accountPermissionsStorage().allAdmins.add(_account);\n        } else {\n            _accountPermissionsStorage().allAdmins.remove(_account);\n        }\n\n        emit AdminUpdated(_account, _isAdmin);\n    }\n\n    /// @dev Returns the address of the signer of the request.\n    function _recoverAddress(bytes memory _encoded, bytes calldata _signature) internal view virtual returns (address) {\n        return _hashTypedDataV4(keccak256(_encoded)).recover(_signature);\n    }\n\n    /// @dev Encodes a request for recovery of the signer in `recoverAddress`.\n    function _encodeRequest(SignerPermissionRequest calldata _req) internal pure virtual returns (bytes memory) {\n        return\n            abi.encode(\n                TYPEHASH,\n                _req.signer,\n                _req.isAdmin,\n                keccak256(abi.encodePacked(_req.approvedTargets)),\n                _req.nativeTokenLimitPerTransaction,\n                _req.permissionStartTimestamp,\n                _req.permissionEndTimestamp,\n                _req.reqValidityStartTimestamp,\n                _req.reqValidityEndTimestamp,\n                _req.uid\n            );\n    }\n\n    /// @dev Returns the AccountPermissions storage.\n    function _accountPermissionsStorage() internal pure returns (AccountPermissionsStorage.Data storage data) {\n        data = AccountPermissionsStorage.data();\n    }\n}\n"
      },
      "contracts/extension/upgradeable/ContractMetadata.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../interface/IContractMetadata.sol\";\n\n/**\n *  @author  thirdweb.com\n *\n *  @title   Contract Metadata\n *  @notice  Thirdweb's `ContractMetadata` is a contract extension for any base contracts. It lets you set a metadata URI\n *           for you contract.\n *           Additionally, `ContractMetadata` is necessary for NFT contracts that want royalties to get distributed on OpenSea.\n */\n\nlibrary ContractMetadataStorage {\n    /// @custom:storage-location erc7201:contract.metadata.storage\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"contract.metadata.storage\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 public constant CONTRACT_METADATA_STORAGE_POSITION =\n        0x4bc804ba64359c0e35e5ed5d90ee596ecaa49a3a930ddcb1470ea0dd625da900;\n\n    struct Data {\n        /// @notice Returns the contract metadata URI.\n        string contractURI;\n    }\n\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = CONTRACT_METADATA_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}\n\nabstract contract ContractMetadata is IContractMetadata {\n    /**\n     *  @notice         Lets a contract admin set the URI for contract-level metadata.\n     *  @dev            Caller should be authorized to setup contractURI, e.g. contract admin.\n     *                  See {_canSetContractURI}.\n     *                  Emits {ContractURIUpdated Event}.\n     *\n     *  @param _uri     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     */\n    function setContractURI(string memory _uri) external override {\n        if (!_canSetContractURI()) {\n            revert(\"Not authorized\");\n        }\n\n        _setupContractURI(_uri);\n    }\n\n    /// @dev Lets a contract admin set the URI for contract-level metadata.\n    function _setupContractURI(string memory _uri) internal {\n        string memory prevURI = _contractMetadataStorage().contractURI;\n        _contractMetadataStorage().contractURI = _uri;\n\n        emit ContractURIUpdated(prevURI, _uri);\n    }\n\n    /// @notice Returns the contract metadata URI.\n    function contractURI() public view virtual override returns (string memory) {\n        return _contractMetadataStorage().contractURI;\n    }\n\n    /// @dev Returns the AccountPermissions storage.\n    function _contractMetadataStorage() internal pure returns (ContractMetadataStorage.Data storage data) {\n        data = ContractMetadataStorage.data();\n    }\n\n    /// @dev Returns whether contract metadata can be set in the given execution context.\n    function _canSetContractURI() internal view virtual returns (bool);\n}\n"
      },
      "contracts/extension/upgradeable/Initializable.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.0;\n\nimport \"../../lib/Address.sol\";\n\nlibrary InitStorage {\n    /// @custom:storage-location erc7201:init.storage\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"init.storage\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 constant INIT_STORAGE_POSITION = 0x322cf19c484104d3b1a9c2982ebae869ede3fa5f6c4703ca41b9a48c76ee0300;\n\n    /// @dev Layout of the entrypoint contract's storage.\n    struct Data {\n        uint8 initialized;\n        bool initializing;\n    }\n\n    /// @dev Returns the entrypoint contract's data at the relevant storage location.\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = INIT_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}\n\nabstract contract Initializable {\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        uint8 _initialized = _initStorage().initialized;\n        bool _initializing = _initStorage().initializing;\n\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initStorage().initialized = 1;\n        if (isTopLevelCall) {\n            _initStorage().initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initStorage().initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        uint8 _initialized = _initStorage().initialized;\n        bool _initializing = _initStorage().initializing;\n\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initStorage().initialized = version;\n        _initStorage().initializing = true;\n        _;\n        _initStorage().initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initStorage().initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        uint8 _initialized = _initStorage().initialized;\n        bool _initializing = _initStorage().initializing;\n\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized < type(uint8).max) {\n            _initStorage().initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /// @dev Returns the InitStorage storage.\n    function _initStorage() internal pure returns (InitStorage.Data storage data) {\n        data = InitStorage.data();\n    }\n}\n"
      },
      "contracts/extension/upgradeable/Permissions.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../interface/IPermissions.sol\";\nimport \"../../lib/Strings.sol\";\n\n/**\n *  @title   Permissions\n *  @dev     This contracts provides extending-contracts with role-based access control mechanisms\n */\n\nlibrary PermissionsStorage {\n    /// @custom:storage-location erc7201:permissions.storage\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"permissions.storage\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 public constant PERMISSIONS_STORAGE_POSITION =\n        0x0a7b0f5c59907924802379ebe98cdc23e2ee7820f63d30126e10b3752010e500;\n\n    struct Data {\n        /// @dev Map from keccak256 hash of a role => a map from address => whether address has role.\n        mapping(bytes32 => mapping(address => bool)) _hasRole;\n        /// @dev Map from keccak256 hash of a role to role admin. See {getRoleAdmin}.\n        mapping(bytes32 => bytes32) _getRoleAdmin;\n    }\n\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = PERMISSIONS_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}\n\ncontract Permissions is IPermissions {\n    /// @dev Default admin role for all roles. Only accounts with this role can grant/revoke other roles.\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /// @dev Modifier that checks if an account has the specified role; reverts otherwise.\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role, _msgSender());\n        _;\n    }\n\n    /**\n     *  @notice         Checks whether an account has a particular role.\n     *  @dev            Returns `true` if `account` has been granted `role`.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param account  Address of the account for which the role is being checked.\n     */\n    function hasRole(bytes32 role, address account) public view override returns (bool) {\n        return _permissionsStorage()._hasRole[role][account];\n    }\n\n    /**\n     *  @notice         Checks whether an account has a particular role;\n     *                  role restrictions can be swtiched on and off.\n     *\n     *  @dev            Returns `true` if `account` has been granted `role`.\n     *                  Role restrictions can be swtiched on and off:\n     *                      - If address(0) has ROLE, then the ROLE restrictions\n     *                        don't apply.\n     *                      - If address(0) does not have ROLE, then the ROLE\n     *                        restrictions will apply.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param account  Address of the account for which the role is being checked.\n     */\n    function hasRoleWithSwitch(bytes32 role, address account) public view returns (bool) {\n        if (!_permissionsStorage()._hasRole[role][address(0)]) {\n            return _permissionsStorage()._hasRole[role][account];\n        }\n\n        return true;\n    }\n\n    /**\n     *  @notice         Returns the admin role that controls the specified role.\n     *  @dev            See {grantRole} and {revokeRole}.\n     *                  To change a role's admin, use {_setRoleAdmin}.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     */\n    function getRoleAdmin(bytes32 role) external view override returns (bytes32) {\n        return _permissionsStorage()._getRoleAdmin[role];\n    }\n\n    /**\n     *  @notice         Grants a role to an account, if not previously granted.\n     *  @dev            Caller must have admin role for the `role`.\n     *                  Emits {RoleGranted Event}.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param account  Address of the account to which the role is being granted.\n     */\n    function grantRole(bytes32 role, address account) public virtual override {\n        _checkRole(_permissionsStorage()._getRoleAdmin[role], _msgSender());\n        if (_permissionsStorage()._hasRole[role][account]) {\n            revert(\"Can only grant to non holders\");\n        }\n        _setupRole(role, account);\n    }\n\n    /**\n     *  @notice         Revokes role from an account.\n     *  @dev            Caller must have admin role for the `role`.\n     *                  Emits {RoleRevoked Event}.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param account  Address of the account from which the role is being revoked.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override {\n        _checkRole(_permissionsStorage()._getRoleAdmin[role], _msgSender());\n        _revokeRole(role, account);\n    }\n\n    /**\n     *  @notice         Revokes role from the account.\n     *  @dev            Caller must have the `role`, with caller being the same as `account`.\n     *                  Emits {RoleRevoked Event}.\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param account  Address of the account from which the role is being revoked.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        if (_msgSender() != account) {\n            revert(\"Can only renounce for self\");\n        }\n        _revokeRole(role, account);\n    }\n\n    /// @dev Sets `adminRole` as `role`'s admin role.\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = _permissionsStorage()._getRoleAdmin[role];\n        _permissionsStorage()._getRoleAdmin[role] = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /// @dev Sets up `role` for `account`\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _permissionsStorage()._hasRole[role][account] = true;\n        emit RoleGranted(role, account, _msgSender());\n    }\n\n    /// @dev Revokes `role` from `account`\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        _checkRole(role, account);\n        delete _permissionsStorage()._hasRole[role][account];\n        emit RoleRevoked(role, account, _msgSender());\n    }\n\n    /// @dev Checks `role` for `account`. Reverts with a message including the required role.\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!_permissionsStorage()._hasRole[role][account]) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"Permissions: account \",\n                        Strings.toHexString(uint160(account), 20),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /// @dev Checks `role` for `account`. Reverts with a message including the required role.\n    function _checkRoleWithSwitch(bytes32 role, address account) internal view virtual {\n        if (!hasRoleWithSwitch(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"Permissions: account \",\n                        Strings.toHexString(uint160(account), 20),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    function _msgSender() internal view virtual returns (address sender) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /// @dev Returns the Permissions storage.\n    function _permissionsStorage() internal pure returns (PermissionsStorage.Data storage data) {\n        data = PermissionsStorage.data();\n    }\n}\n"
      },
      "contracts/extension/upgradeable/PermissionsEnumerable.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\nimport \"../interface/IPermissionsEnumerable.sol\";\nimport \"./Permissions.sol\";\n\n/**\n *  @title   PermissionsEnumerable\n *  @dev     This contracts provides extending-contracts with role-based access control mechanisms.\n *           Also provides interfaces to view all members with a given role, and total count of members.\n */\n\nlibrary PermissionsEnumerableStorage {\n    /// @custom:storage-location erc7201:extension.manager.storage\n    bytes32 public constant PERMISSIONS_ENUMERABLE_STORAGE_POSITION =\n        keccak256(abi.encode(uint256(keccak256(\"permissions.enumerable.storage\")) - 1)) & ~bytes32(uint256(0xff));\n\n    /**\n     *  @notice A data structure to store data of members for a given role.\n     *\n     *  @param index    Current index in the list of accounts that have a role.\n     *  @param members  map from index => address of account that has a role\n     *  @param indexOf  map from address => index which the account has.\n     */\n    struct RoleMembers {\n        uint256 index;\n        mapping(uint256 => address) members;\n        mapping(address => uint256) indexOf;\n    }\n\n    struct Data {\n        /// @dev map from keccak256 hash of a role to its members' data. See {RoleMembers}.\n        mapping(bytes32 => RoleMembers) roleMembers;\n    }\n\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = PERMISSIONS_ENUMERABLE_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}\n\ncontract PermissionsEnumerable is IPermissionsEnumerable, Permissions {\n    /**\n     *  @notice         Returns the role-member from a list of members for a role,\n     *                  at a given index.\n     *  @dev            Returns `member` who has `role`, at `index` of role-members list.\n     *                  See struct {RoleMembers}, and mapping {roleMembers}\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *  @param index    Index in list of current members for the role.\n     *\n     *  @return member  Address of account that has `role`\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view override returns (address member) {\n        uint256 currentIndex = _permissionsEnumerableStorage().roleMembers[role].index;\n        uint256 check;\n\n        for (uint256 i = 0; i < currentIndex; i += 1) {\n            if (_permissionsEnumerableStorage().roleMembers[role].members[i] != address(0)) {\n                if (check == index) {\n                    member = _permissionsEnumerableStorage().roleMembers[role].members[i];\n                    return member;\n                }\n                check += 1;\n            } else if (\n                hasRole(role, address(0)) && i == _permissionsEnumerableStorage().roleMembers[role].indexOf[address(0)]\n            ) {\n                check += 1;\n            }\n        }\n    }\n\n    /**\n     *  @notice         Returns total number of accounts that have a role.\n     *  @dev            Returns `count` of accounts that have `role`.\n     *                  See struct {RoleMembers}, and mapping {roleMembers}\n     *\n     *  @param role     keccak256 hash of the role. e.g. keccak256(\"TRANSFER_ROLE\")\n     *\n     *  @return count   Total number of accounts that have `role`\n     */\n    function getRoleMemberCount(bytes32 role) external view override returns (uint256 count) {\n        uint256 currentIndex = _permissionsEnumerableStorage().roleMembers[role].index;\n\n        for (uint256 i = 0; i < currentIndex; i += 1) {\n            if (_permissionsEnumerableStorage().roleMembers[role].members[i] != address(0)) {\n                count += 1;\n            }\n        }\n        if (hasRole(role, address(0))) {\n            count += 1;\n        }\n    }\n\n    /// @dev Revokes `role` from `account`, and removes `account` from {roleMembers}\n    ///      See {_removeMember}\n    function _revokeRole(bytes32 role, address account) internal virtual override {\n        super._revokeRole(role, account);\n        _removeMember(role, account);\n    }\n\n    /// @dev Grants `role` to `account`, and adds `account` to {roleMembers}\n    ///      See {_addMember}\n    function _setupRole(bytes32 role, address account) internal virtual override {\n        super._setupRole(role, account);\n        _addMember(role, account);\n    }\n\n    /// @dev adds `account` to {roleMembers}, for `role`\n    function _addMember(bytes32 role, address account) internal {\n        uint256 idx = _permissionsEnumerableStorage().roleMembers[role].index;\n        _permissionsEnumerableStorage().roleMembers[role].index += 1;\n\n        _permissionsEnumerableStorage().roleMembers[role].members[idx] = account;\n        _permissionsEnumerableStorage().roleMembers[role].indexOf[account] = idx;\n    }\n\n    /// @dev removes `account` from {roleMembers}, for `role`\n    function _removeMember(bytes32 role, address account) internal {\n        uint256 idx = _permissionsEnumerableStorage().roleMembers[role].indexOf[account];\n\n        delete _permissionsEnumerableStorage().roleMembers[role].members[idx];\n        delete _permissionsEnumerableStorage().roleMembers[role].indexOf[account];\n    }\n\n    /// @dev Returns the PermissionsEnumerable storage.\n    function _permissionsEnumerableStorage() internal pure returns (PermissionsEnumerableStorage.Data storage data) {\n        data = PermissionsEnumerableStorage.data();\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/proxy/Clones.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create(0, 0x09, 0x37)\n        }\n        require(instance != address(0), \"ERC1167: create failed\");\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create2(0, 0x09, 0x37, salt)\n        }\n        require(instance != address(0), \"ERC1167: create2 failed\");\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(add(ptr, 0x38), deployer)\n            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n            mstore(add(ptr, 0x14), implementation)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n            mstore(add(ptr, 0x58), salt)\n            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n            predicted := keccak256(add(ptr, 0x43), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt\n    ) internal view returns (address predicted) {\n        return predictDeterministicAddress(implementation, salt, address(this));\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/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 \"../../../../eip/interface/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"
      },
      "contracts/external-deps/openzeppelin/token/ERC1155/utils/ERC1155Holder.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ERC1155Receiver.sol\";\n\n/**\n * Simple implementation of `ERC1155Receiver` that will allow a contract to hold ERC1155 tokens.\n *\n * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be\n * stuck.\n *\n * @dev _Available since v3.1._\n */\ncontract ERC1155Holder is ERC1155Receiver {\n    function onERC1155Received(\n        address,\n        address,\n        uint256,\n        uint256,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155Received.selector;\n    }\n\n    function onERC1155BatchReceived(\n        address,\n        address,\n        uint256[] memory,\n        uint256[] memory,\n        bytes memory\n    ) public virtual override returns (bytes4) {\n        return this.onERC1155BatchReceived.selector;\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/token/ERC1155/utils/ERC1155Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC1155Receiver.sol\";\nimport \"../../../../../eip/ERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\nabstract contract ERC1155Receiver is ERC165, IERC1155Receiver {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/token/ERC721/IERC721Receiver.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 `IERC721.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"
      },
      "contracts/external-deps/openzeppelin/token/ERC721/utils/ERC721Holder.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Receiver.sol\";\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract ERC721Holder is IERC721Receiver {\n    /**\n     * @dev See {IERC721Receiver-onERC721Received}.\n     *\n     * Always returns `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(address, address, uint256, bytes memory) public virtual override returns (bytes4) {\n        return this.onERC721Received.selector;\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/utils/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../../../lib/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"
      },
      "contracts/external-deps/openzeppelin/utils/cryptography/EIP712.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n    /* solhint-disable var-name-mixedcase */\n    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n    // invalidate the cached domain separator if the chain id changes.\n    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n    uint256 private immutable _CACHED_CHAIN_ID;\n    address private immutable _CACHED_THIS;\n\n    bytes32 private immutable _HASHED_NAME;\n    bytes32 private immutable _HASHED_VERSION;\n    bytes32 private immutable _TYPE_HASH;\n\n    /* solhint-enable var-name-mixedcase */\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    constructor(string memory name, string memory version) {\n        bytes32 hashedName = keccak256(bytes(name));\n        bytes32 hashedVersion = keccak256(bytes(version));\n        bytes32 typeHash = keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n        _HASHED_NAME = hashedName;\n        _HASHED_VERSION = hashedVersion;\n        _CACHED_CHAIN_ID = block.chainid;\n        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n        _CACHED_THIS = address(this);\n        _TYPE_HASH = typeHash;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n            return _CACHED_DOMAIN_SEPARATOR;\n        } else {\n            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n        }\n    }\n\n    function _buildDomainSeparator(\n        bytes32 typeHash,\n        bytes32 nameHash,\n        bytes32 versionHash\n    ) private view returns (bytes32) {\n        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n}\n"
      },
      "contracts/external-deps/openzeppelin/utils/structs/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n *  Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n *  See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n *  In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(bytes32 => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        return _values(set._inner);\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n}\n"
      },
      "contracts/lib/Address.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.1;\n\n/// @author thirdweb, OpenZeppelin Contracts (v4.9.0)\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"
      },
      "contracts/lib/BytesLib.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n/// Credits: https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol\n\nlibrary BytesLib {\n    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {\n        require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n        address tempAddress;\n\n        assembly {\n            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n        }\n\n        return tempAddress;\n    }\n}\n"
      },
      "contracts/lib/Strings.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.0;\n\n/// @author thirdweb\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\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        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\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        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\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] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\", encoded using 2 hexadecimal digits per byte,\n    /// and the alphabets are capitalized conditionally according to\n    /// https://eips.ethereum.org/EIPS/eip-55\n    function toHexStringChecksummed(address value) internal pure returns (string memory str) {\n        str = toHexString(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let mask := shl(6, div(not(0), 255)) // `0b010000000100000000 ...`\n            let o := add(str, 0x22)\n            let hashed := and(keccak256(o, 40), mul(34, mask)) // `0b10001000 ... `\n            let t := shl(240, 136) // `0b10001000 << 240`\n            for {\n                let i := 0\n            } 1 {\n\n            } {\n                mstore(add(i, i), mul(t, byte(i, hashed)))\n                i := add(i, 1)\n                if eq(i, 20) {\n                    break\n                }\n            }\n            mstore(o, xor(mload(o), shr(1, and(mload(0x00), and(mload(o), mask)))))\n            o := add(o, 0x20)\n            mstore(o, xor(mload(o), shr(1, and(mload(0x20), and(mload(o), mask)))))\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is prefixed with \"0x\" and encoded using 2 hexadecimal digits per byte.\n    function toHexString(address value) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(value);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hexadecimal representation of `value`.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(address value) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            str := mload(0x40)\n\n            // Allocate the memory.\n            // We need 0x20 bytes for the trailing zeros padding, 0x20 bytes for the length,\n            // 0x02 bytes for the prefix, and 0x28 bytes for the digits.\n            // The next multiple of 0x20 above (0x20 + 0x20 + 0x02 + 0x28) is 0x80.\n            mstore(0x40, add(str, 0x80))\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            str := add(str, 2)\n            mstore(str, 40)\n\n            let o := add(str, 0x20)\n            mstore(add(o, 40), 0)\n\n            value := shl(96, value)\n\n            // We write the string from rightmost digit to leftmost digit.\n            // The following is essentially a do-while loop that also handles the zero case.\n            for {\n                let i := 0\n            } 1 {\n\n            } {\n                let p := add(o, add(i, i))\n                let temp := byte(i, value)\n                mstore8(add(p, 1), mload(and(temp, 15)))\n                mstore8(p, mload(shr(4, temp)))\n                i := add(i, 1)\n                if eq(i, 20) {\n                    break\n                }\n            }\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexString(bytes memory raw) internal pure returns (string memory str) {\n        str = toHexStringNoPrefix(raw);\n        /// @solidity memory-safe-assembly\n        assembly {\n            let strLength := add(mload(str), 2) // Compute the length.\n            mstore(str, 0x3078) // Write the \"0x\" prefix.\n            str := sub(str, 2) // Move the pointer.\n            mstore(str, strLength) // Write the length.\n        }\n    }\n\n    /// @dev Returns the hex encoded string from the raw bytes.\n    /// The output is encoded using 2 hexadecimal digits per byte.\n    function toHexStringNoPrefix(bytes memory raw) internal pure returns (string memory str) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let length := mload(raw)\n            str := add(mload(0x40), 2) // Skip 2 bytes for the optional prefix.\n            mstore(str, add(length, length)) // Store the length of the output.\n\n            // Store \"0123456789abcdef\" in scratch space.\n            mstore(0x0f, 0x30313233343536373839616263646566)\n\n            let o := add(str, 0x20)\n            let end := add(raw, length)\n\n            for {\n\n            } iszero(eq(raw, end)) {\n\n            } {\n                raw := add(raw, 1)\n                mstore8(add(o, 1), mload(and(mload(raw), 15)))\n                mstore8(o, mload(and(shr(4, mload(raw)), 15)))\n                o := add(o, 2)\n            }\n            mstore(o, 0) // Zeroize the slot after the string.\n            mstore(0x40, add(o, 0x20)) // Allocate the memory.\n        }\n    }\n}\n"
      },
      "contracts/prebuilts/account/interface/IAccount.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../utils/UserOperation.sol\";\n\ninterface IAccount {\n    /**\n     * Validate user's signature and nonce\n     * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n     * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n     * This allows making a \"simulation call\" without a valid signature\n     * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n     *\n     * @dev Must validate caller is the entryPoint.\n     *      Must validate the signature and nonce\n     * @param userOp the operation that is about to be executed.\n     * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n     * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n     *      This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n     *      The excess is left as a deposit in the entrypoint, for future calls.\n     *      can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n     *      In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n     * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n     *      <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n     *         otherwise, an address of an \"authorizer\" contract.\n     *      <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n     *      <6-byte> validAfter - first timestamp this operation is valid\n     *      If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n     *      Note that the validation code cannot use block.timestamp (or block.number) directly.\n     */\n    function validateUserOp(\n        UserOperation calldata userOp,\n        bytes32 userOpHash,\n        uint256 missingAccountFunds\n    ) external returns (uint256 validationData);\n}\n"
      },
      "contracts/prebuilts/account/interface/IAccountCore.sol": {
        "content": "// SPDX-License-Identifier: Apache 2.0\npragma solidity ^0.8.12;\n\nimport \"./IAccount.sol\";\nimport \"../../../extension/interface/IAccountPermissions.sol\";\nimport \"../../../extension/interface/IMulticall.sol\";\n\ninterface IAccountCore is IAccount, IAccountPermissions, IMulticall {\n    /// @dev Returns the address of the factory from which the account was created.\n    function factory() external view returns (address);\n}\n"
      },
      "contracts/prebuilts/account/interface/IAccountFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./IAccountFactoryCore.sol\";\n\ninterface IAccountFactory is IAccountFactoryCore {\n    /*///////////////////////////////////////////////////////////////\n                        Callback Functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Callback function for an Account to register its signers.\n    function onSignerAdded(address signer, bytes32 salt) external;\n\n    /// @notice Callback function for an Account to un-register its signers.\n    function onSignerRemoved(address signer, bytes32 salt) external;\n}\n"
      },
      "contracts/prebuilts/account/interface/IAccountFactoryCore.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface IAccountFactoryCore {\n    /*///////////////////////////////////////////////////////////////\n                                Events\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Emitted when a new Account is created.\n    event AccountCreated(address indexed account, address indexed accountAdmin);\n\n    /// @notice Emitted when a new signer is added to an Account.\n    event SignerAdded(address indexed account, address indexed signer);\n\n    /// @notice Emitted when a new signer is added to an Account.\n    event SignerRemoved(address indexed account, address indexed signer);\n\n    /*///////////////////////////////////////////////////////////////\n                        Extension Functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Deploys a new Account for admin.\n    function createAccount(address admin, bytes calldata _data) external returns (address account);\n\n    /*///////////////////////////////////////////////////////////////\n                            View Functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns the address of the Account implementation.\n    function accountImplementation() external view returns (address);\n\n    /// @notice Returns all accounts created on the factory.\n    function getAllAccounts() external view returns (address[] memory);\n\n    /// @notice Returns the address of an Account that would be deployed with the given admin signer.\n    function getAddress(address adminSigner, bytes calldata data) external view returns (address);\n\n    /// @notice Returns all accounts on which a signer has (active or inactive) permissions.\n    function getAccountsOfSigner(address signer) external view returns (address[] memory accounts);\n}\n"
      },
      "contracts/prebuilts/account/interface/IAggregator.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../utils/UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n    /**\n     * validate aggregated signature.\n     * revert if the aggregated signature does not match the given list of operations.\n     */\n    function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n    /**\n     * validate signature of a single userOp\n     * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n     * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n     * @param userOp the userOperation received from the user.\n     * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n     *    (usually empty, unless account and aggregator support some kind of \"multisig\"\n     */\n    function validateUserOpSignature(UserOperation calldata userOp) external view returns (bytes memory sigForUserOp);\n\n    /**\n     * aggregate multiple signatures into a single value.\n     * This method is called off-chain to calculate the signature to pass with handleOps()\n     * bundler MAY use optimized custom code perform this aggregation\n     * @param userOps array of UserOperations to collect the signatures from.\n     * @return aggregatedSignature the aggregated signature\n     */\n    function aggregateSignatures(\n        UserOperation[] calldata userOps\n    ) external view returns (bytes memory aggregatedSignature);\n}\n"
      },
      "contracts/prebuilts/account/interface/IEntrypoint.sol": {
        "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"../utils/UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n    /***\n     * An event emitted after each successful request\n     * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n     * @param sender - the account that generates this request.\n     * @param paymaster - if non-null, the paymaster that pays for this request.\n     * @param nonce - the nonce value from the request.\n     * @param success - true if the sender transaction succeeded, false if reverted.\n     * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n     * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n     */\n    event UserOperationEvent(\n        bytes32 indexed userOpHash,\n        address indexed sender,\n        address indexed paymaster,\n        uint256 nonce,\n        bool success,\n        uint256 actualGasCost,\n        uint256 actualGasUsed\n    );\n\n    /**\n     * account \"sender\" was deployed.\n     * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n     * @param sender the account that is deployed\n     * @param factory the factory used to deploy this account (in the initCode)\n     * @param paymaster the paymaster used by this UserOp\n     */\n    event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n    /**\n     * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n     * @param userOpHash the request unique identifier.\n     * @param sender the sender of this request\n     * @param nonce the nonce used in the request\n     * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n     */\n    event UserOperationRevertReason(\n        bytes32 indexed userOpHash,\n        address indexed sender,\n        uint256 nonce,\n        bytes revertReason\n    );\n\n    /**\n     * an event emitted by handleOps(), before starting the execution loop.\n     * any event emitted before this event, is part of the validation.\n     */\n    event BeforeExecution();\n\n    /**\n     * signature aggregator used by the following UserOperationEvents within this bundle.\n     */\n    event SignatureAggregatorChanged(address indexed aggregator);\n\n    /**\n     * a custom revert error of handleOps, to identify the offending op.\n     *  NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n     *  @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n     *  @param reason - revert reason\n     *      The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n     *      so a failure can be attributed to the correct entity.\n     *   Should be caught in off-chain handleOps simulation and not happen on-chain.\n     *   Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n     */\n    error FailedOp(uint256 opIndex, string reason);\n\n    /**\n     * error case when a signature aggregator fails to verify the aggregated signature it had created.\n     */\n    error SignatureValidationFailed(address aggregator);\n\n    /**\n     * Successful result from simulateValidation.\n     * @param returnInfo gas and time-range returned values\n     * @param senderInfo stake information about the sender\n     * @param factoryInfo stake information about the factory (if any)\n     * @param paymasterInfo stake information about the paymaster (if any)\n     */\n    error ValidationResult(ReturnInfo returnInfo, StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n    /**\n     * Successful result from simulateValidation, if the account returns a signature aggregator\n     * @param returnInfo gas and time-range returned values\n     * @param senderInfo stake information about the sender\n     * @param factoryInfo stake information about the factory (if any)\n     * @param paymasterInfo stake information about the paymaster (if any)\n     * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n     *      bundler MUST use it to verify the signature, or reject the UserOperation\n     */\n    error ValidationResultWithAggregation(\n        ReturnInfo returnInfo,\n        StakeInfo senderInfo,\n        StakeInfo factoryInfo,\n        StakeInfo paymasterInfo,\n        AggregatorStakeInfo aggregatorInfo\n    );\n\n    /**\n     * return value of getSenderAddress\n     */\n    error SenderAddressResult(address sender);\n\n    /**\n     * return value of simulateHandleOp\n     */\n    error ExecutionResult(\n        uint256 preOpGas,\n        uint256 paid,\n        uint48 validAfter,\n        uint48 validUntil,\n        bool targetSuccess,\n        bytes targetResult\n    );\n\n    //UserOps handled, per aggregator\n    struct UserOpsPerAggregator {\n        UserOperation[] userOps;\n        // aggregator address\n        IAggregator aggregator;\n        // aggregated signature\n        bytes signature;\n    }\n\n    /**\n     * Execute a batch of UserOperation.\n     * no signature aggregator is used.\n     * if any account requires an aggregator (that is, it returned an aggregator when\n     * performing simulateValidation), then handleAggregatedOps() must be used instead.\n     * @param ops the operations to execute\n     * @param beneficiary the address to receive the fees\n     */\n    function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n    /**\n     * Execute a batch of UserOperation with Aggregators\n     * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n     * @param beneficiary the address to receive the fees\n     */\n    function handleAggregatedOps(\n        UserOpsPerAggregator[] calldata opsPerAggregator,\n        address payable beneficiary\n    ) external;\n\n    /**\n     * generate a request Id - unique identifier for this request.\n     * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n     */\n    function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n    /**\n     * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n     * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n     * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n     * @param userOp the user operation to validate.\n     */\n    function simulateValidation(UserOperation calldata userOp) external;\n\n    /**\n     * gas and return values during simulation\n     * @param preOpGas the gas used for validation (including preValidationGas)\n     * @param prefund the required prefund for this operation\n     * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n     * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n     * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n     * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n     */\n    struct ReturnInfo {\n        uint256 preOpGas;\n        uint256 prefund;\n        bool sigFailed;\n        uint48 validAfter;\n        uint48 validUntil;\n        bytes paymasterContext;\n    }\n\n    /**\n     * returned aggregated signature info.\n     * the aggregator returned by the account, and its current stake.\n     */\n    struct AggregatorStakeInfo {\n        address aggregator;\n        StakeInfo stakeInfo;\n    }\n\n    /**\n     * Get counterfactual sender address.\n     *  Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n     * this method always revert, and returns the address in SenderAddressResult error\n     * @param initCode the constructor code to be passed into the UserOperation.\n     */\n    function getSenderAddress(bytes memory initCode) external;\n\n    /**\n     * simulate full execution of a UserOperation (including both validation and target execution)\n     * this method will always revert with \"ExecutionResult\".\n     * it performs full validation of the UserOperation, but ignores signature error.\n     * an optional target address is called after the userop succeeds, and its value is returned\n     * (before the entire call is reverted)\n     * Note that in order to collect the success/failure of the target call, it must be executed\n     * with trace enabled to track the emitted events.\n     * @param op the UserOperation to simulate\n     * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n     *        are set to the return from that call.\n     * @param targetCallData callData to pass to target address\n     */\n    function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n"
      },
      "contracts/prebuilts/account/interface/INonceManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n    /**\n     * Return the next nonce for this sender.\n     * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n     * But UserOp with different keys can come with arbitrary order.\n     *\n     * @param sender the account address\n     * @param key the high 192 bit of the nonce\n     * @return nonce a full nonce to pass for next UserOp with this sender.\n     */\n    function getNonce(address sender, uint192 key) external view returns (uint256 nonce);\n\n    /**\n     * Manually increment the nonce of the sender.\n     * This method is exposed just for completeness..\n     * Account does NOT need to call it, neither during validation, nor elsewhere,\n     * as the EntryPoint will update the nonce regardless.\n     * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n     * UserOperations will not pay extra for the first transaction with a given key.\n     */\n    function incrementNonce(uint192 key) external;\n}\n"
      },
      "contracts/prebuilts/account/interface/IStakeManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n    event Deposited(address indexed account, uint256 totalDeposit);\n\n    event Withdrawn(address indexed account, address withdrawAddress, uint256 amount);\n\n    /// Emitted when stake or unstake delay are modified\n    event StakeLocked(address indexed account, uint256 totalStaked, uint256 unstakeDelaySec);\n\n    /// Emitted once a stake is scheduled for withdrawal\n    event StakeUnlocked(address indexed account, uint256 withdrawTime);\n\n    event StakeWithdrawn(address indexed account, address withdrawAddress, uint256 amount);\n\n    /**\n     * @param deposit the entity's deposit\n     * @param staked true if this entity is staked.\n     * @param stake actual amount of ether staked for this entity.\n     * @param unstakeDelaySec minimum delay to withdraw the stake.\n     * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n     * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n     *    and the rest fit into a 2nd cell.\n     *    112 bit allows for 10^15 eth\n     *    48 bit for full timestamp\n     *    32 bit allows 150 years for unstake delay\n     */\n    struct DepositInfo {\n        uint112 deposit;\n        bool staked;\n        uint112 stake;\n        uint32 unstakeDelaySec;\n        uint48 withdrawTime;\n    }\n\n    //API struct used by getStakeInfo and simulateValidation\n    struct StakeInfo {\n        uint256 stake;\n        uint256 unstakeDelaySec;\n    }\n\n    /// @return info - full deposit information of given account\n    function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n    /// @return the deposit (for gas payment) of the account\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * add to the deposit of the given account\n     */\n    function depositTo(address account) external payable;\n\n    /**\n     * add to the account's stake - amount and delay\n     * any pending unstake is first cancelled.\n     * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n     */\n    function addStake(uint32 _unstakeDelaySec) external payable;\n\n    /**\n     * attempt to unlock the stake.\n     * the value can be withdrawn (using withdrawStake) after the unstake delay.\n     */\n    function unlockStake() external;\n\n    /**\n     * withdraw from the (unlocked) stake.\n     * must first call unlockStake and wait for the unstakeDelay to pass\n     * @param withdrawAddress the address to send withdrawn value.\n     */\n    function withdrawStake(address payable withdrawAddress) external;\n\n    /**\n     * withdraw from the deposit.\n     * @param withdrawAddress the address to send withdrawn value.\n     * @param withdrawAmount the amount to withdraw.\n     */\n    function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
      },
      "contracts/prebuilts/account/managed/ManagedAccount.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.11;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\n//   $$\\     $$\\       $$\\                 $$\\                         $$\\\n//   $$ |    $$ |      \\__|                $$ |                        $$ |\n// $$$$$$\\   $$$$$$$\\  $$\\  $$$$$$\\   $$$$$$$ |$$\\  $$\\  $$\\  $$$$$$\\  $$$$$$$\\\n// \\_$$  _|  $$  __$$\\ $$ |$$  __$$\\ $$  __$$ |$$ | $$ | $$ |$$  __$$\\ $$  __$$\\\n//   $$ |    $$ |  $$ |$$ |$$ |  \\__|$$ /  $$ |$$ | $$ | $$ |$$$$$$$$ |$$ |  $$ |\n//   $$ |$$\\ $$ |  $$ |$$ |$$ |      $$ |  $$ |$$ | $$ | $$ |$$   ____|$$ |  $$ |\n//   \\$$$$  |$$ |  $$ |$$ |$$ |      \\$$$$$$$ |\\$$$$$\\$$$$  |\\$$$$$$$\\ $$$$$$$  |\n//    \\____/ \\__|  \\__|\\__|\\__|       \\_______| \\_____\\____/  \\_______|\\_______/\n\nimport \"../utils/AccountCore.sol\";\nimport \"@thirdweb-dev/dynamic-contracts/src/core/Router.sol\";\nimport \"@thirdweb-dev/dynamic-contracts/src/interface/IRouterState.sol\";\n\ncontract ManagedAccount is AccountCore, Router, IRouterState {\n    constructor(IEntryPoint _entrypoint, address _factory) AccountCore(_entrypoint, _factory) {}\n\n    /// @notice Returns the implementation contract address for a given function signature.\n    function getImplementationForFunction(bytes4 _functionSelector) public view virtual override returns (address) {\n        return Router(payable(factory)).getImplementationForFunction(_functionSelector);\n    }\n\n    /// @notice Returns all extensions of the Router.\n    function getAllExtensions() external view returns (Extension[] memory) {\n        return IRouterState(payable(factory)).getAllExtensions();\n    }\n}\n"
      },
      "contracts/prebuilts/account/managed/ManagedAccountFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// Utils\nimport \"@thirdweb-dev/dynamic-contracts/src/presets/BaseRouter.sol\";\nimport \"../utils/BaseAccountFactory.sol\";\n\n// Extensions\nimport \"../../../extension/upgradeable//PermissionsEnumerable.sol\";\nimport \"../../../extension/upgradeable//ContractMetadata.sol\";\n\n// Smart wallet implementation\nimport { ManagedAccount, IEntryPoint } from \"./ManagedAccount.sol\";\n\n//   $$\\     $$\\       $$\\                 $$\\                         $$\\\n//   $$ |    $$ |      \\__|                $$ |                        $$ |\n// $$$$$$\\   $$$$$$$\\  $$\\  $$$$$$\\   $$$$$$$ |$$\\  $$\\  $$\\  $$$$$$\\  $$$$$$$\\\n// \\_$$  _|  $$  __$$\\ $$ |$$  __$$\\ $$  __$$ |$$ | $$ | $$ |$$  __$$\\ $$  __$$\\\n//   $$ |    $$ |  $$ |$$ |$$ |  \\__|$$ /  $$ |$$ | $$ | $$ |$$$$$$$$ |$$ |  $$ |\n//   $$ |$$\\ $$ |  $$ |$$ |$$ |      $$ |  $$ |$$ | $$ | $$ |$$   ____|$$ |  $$ |\n//   \\$$$$  |$$ |  $$ |$$ |$$ |      \\$$$$$$$ |\\$$$$$\\$$$$  |\\$$$$$$$\\ $$$$$$$  |\n//    \\____/ \\__|  \\__|\\__|\\__|       \\_______| \\_____\\____/  \\_______|\\_______/\n\ncontract ManagedAccountFactory is BaseAccountFactory, ContractMetadata, PermissionsEnumerable, BaseRouter {\n    /*///////////////////////////////////////////////////////////////\n                            Constructor\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(\n        address _defaultAdmin,\n        IEntryPoint _entrypoint,\n        Extension[] memory _defaultExtensions\n    )\n        BaseRouter(_defaultExtensions)\n        BaseAccountFactory(payable(address(new ManagedAccount(_entrypoint, address(this)))), address(_entrypoint))\n    {\n        __BaseRouter_init();\n        _setupRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);\n\n        bytes32 _extensionRole = keccak256(\"EXTENSION_ROLE\");\n        _setupRole(_extensionRole, _defaultAdmin);\n        _setRoleAdmin(_extensionRole, _extensionRole);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Called in `createAccount`. Initializes the account contract created in `createAccount`.\n    function _initializeAccount(address _account, address _admin, bytes calldata _data) internal override {\n        ManagedAccount(payable(_account)).initialize(_admin, _data);\n    }\n\n    /// @dev Returns whether all relevant permission and other checks are met before any upgrade.\n    function _isAuthorizedCallToUpgrade() internal view virtual override returns (bool) {\n        return hasRole(keccak256(\"EXTENSION_ROLE\"), msg.sender);\n    }\n\n    /// @dev Returns whether contract metadata can be set in the given execution context.\n    function _canSetContractURI() internal view virtual override returns (bool) {\n        return hasRole(DEFAULT_ADMIN_ROLE, msg.sender);\n    }\n\n    /// @notice Returns the sender in the given execution context.\n    function _msgSender() internal view override(Multicall, Permissions) returns (address) {\n        return msg.sender;\n    }\n}\n"
      },
      "contracts/prebuilts/account/utils/AccountCore.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.11;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\n// Base\nimport \"./../utils/BaseAccount.sol\";\n\n// Fixed Extensions\nimport \"../../../extension/Multicall.sol\";\nimport \"../../../extension/upgradeable/Initializable.sol\";\nimport \"../../../extension/upgradeable/AccountPermissions.sol\";\n\n// Utils\nimport \"./Helpers.sol\";\nimport \"./AccountCoreStorage.sol\";\nimport \"./BaseAccountFactory.sol\";\nimport { AccountExtension } from \"./AccountExtension.sol\";\nimport \"../../../external-deps/openzeppelin/utils/cryptography/ECDSA.sol\";\n\nimport \"../interface/IAccountCore.sol\";\n\n//   $$\\     $$\\       $$\\                 $$\\                         $$\\\n//   $$ |    $$ |      \\__|                $$ |                        $$ |\n// $$$$$$\\   $$$$$$$\\  $$\\  $$$$$$\\   $$$$$$$ |$$\\  $$\\  $$\\  $$$$$$\\  $$$$$$$\\\n// \\_$$  _|  $$  __$$\\ $$ |$$  __$$\\ $$  __$$ |$$ | $$ | $$ |$$  __$$\\ $$  __$$\\\n//   $$ |    $$ |  $$ |$$ |$$ |  \\__|$$ /  $$ |$$ | $$ | $$ |$$$$$$$$ |$$ |  $$ |\n//   $$ |$$\\ $$ |  $$ |$$ |$$ |      $$ |  $$ |$$ | $$ | $$ |$$   ____|$$ |  $$ |\n//   \\$$$$  |$$ |  $$ |$$ |$$ |      \\$$$$$$$ |\\$$$$$\\$$$$  |\\$$$$$$$\\ $$$$$$$  |\n//    \\____/ \\__|  \\__|\\__|\\__|       \\_______| \\_____\\____/  \\_______|\\_______/\n\ncontract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, AccountPermissions {\n    using ECDSA for bytes32;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /*///////////////////////////////////////////////////////////////\n                                State\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice EIP 4337 factory for this contract.\n    address public immutable factory;\n\n    /// @notice EIP 4337 Entrypoint contract.\n    IEntryPoint private immutable entrypointContract;\n\n    /*///////////////////////////////////////////////////////////////\n                    Constructor, Initializer, Modifiers\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(IEntryPoint _entrypoint, address _factory) EIP712(\"Account\", \"1\") {\n        _disableInitializers();\n        factory = _factory;\n        entrypointContract = _entrypoint;\n    }\n\n    /// @notice Initializes the smart contract wallet.\n    function initialize(address _defaultAdmin, bytes calldata _data) public virtual initializer {\n        // This is passed as data in the `_registerOnFactory()` call in `AccountExtension` / `Account`.\n        AccountCoreStorage.data().creationSalt = _generateSalt(_defaultAdmin, _data);\n        _setAdmin(_defaultAdmin, true);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns the EIP 4337 entrypoint contract.\n    function entryPoint() public view virtual override returns (IEntryPoint) {\n        address entrypointOverride = AccountCoreStorage.data().entrypointOverride;\n        if (address(entrypointOverride) != address(0)) {\n            return IEntryPoint(entrypointOverride);\n        }\n        return entrypointContract;\n    }\n\n    /** \n    @notice Returns whether a signer is authorized to perform transactions using the account.\n            Validity of the signature is based upon signer permission start/end timestamps, txn target, and txn value.\n            Account admins will always return true, and signers with address(0) as the only approved target will skip target checks.\n\n    @param _signer The signer to check.\n    @param _userOp The user operation to check.\n\n    @return Whether the signer is authorized to perform the transaction.\n    */\n\n    /* solhint-disable*/\n    function isValidSigner(address _signer, UserOperation calldata _userOp) public view virtual returns (bool) {\n        // First, check if the signer is an admin.\n        if (_accountPermissionsStorage().isAdmin[_signer]) {\n            return true;\n        }\n\n        SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[_signer];\n        EnumerableSet.AddressSet storage approvedTargets = _accountPermissionsStorage().approvedTargets[_signer];\n\n        // If not an admin, check if the signer is active.\n        if (\n            permissions.startTimestamp > block.timestamp ||\n            block.timestamp >= permissions.endTimestamp ||\n            approvedTargets.length() == 0\n        ) {\n            // Account: no active permissions.\n            return false;\n        }\n\n        // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.\n        bytes4 sig = getFunctionSignature(_userOp.callData);\n\n        // if address(0) is the only approved target, set isWildCard to true (wildcard approved).\n        bool isWildCard = approvedTargets.length() == 1 && approvedTargets.at(0) == address(0);\n\n        // checking target and value for `execute`\n        if (sig == AccountExtension.execute.selector) {\n            // Extract the `target` and `value` arguments from the calldata for `execute`.\n            (address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);\n\n            // if wildcard target is not approved, check that the target is in the approvedTargets set.\n            if (!isWildCard) {\n                // Check if the target is approved.\n                if (!approvedTargets.contains(target)) {\n                    // Account: target not approved.\n                    return false;\n                }\n            }\n\n            // Check if the value is within the allowed range.\n            if (permissions.nativeTokenLimitPerTransaction < value) {\n                // Account: value too high OR Account: target not approved.\n                return false;\n            }\n        }\n        // checking target and value for `executeBatch`\n        else if (sig == AccountExtension.executeBatch.selector) {\n            // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.\n            (address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);\n\n            // if wildcard target is not approved, check that the targets are in the approvedTargets set.\n            if (!isWildCard) {\n                for (uint256 i = 0; i < targets.length; i++) {\n                    if (!approvedTargets.contains(targets[i])) {\n                        // If any target is not approved, break the loop.\n                        return false;\n                    }\n                }\n            }\n\n            // For each target+value pair, check if the value is within the allowed range.\n            for (uint256 i = 0; i < targets.length; i++) {\n                if (permissions.nativeTokenLimitPerTransaction < values[i]) {\n                    // Account: value too high OR Account: target not approved.\n                    return false;\n                }\n            }\n        } else {\n            // Account: calling invalid fn.\n            return false;\n        }\n\n        return true;\n    }\n\n    /* solhint-enable */\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Overrides the Entrypoint contract being used.\n    function setEntrypointOverride(IEntryPoint _entrypointOverride) public virtual {\n        _onlyAdmin();\n        AccountCoreStorage.data().entrypointOverride = address(_entrypointOverride);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                        Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Returns the salt used when deploying an Account.\n    function _generateSalt(address _admin, bytes memory _data) internal view virtual returns (bytes32) {\n        return keccak256(abi.encode(_admin, _data));\n    }\n\n    function getFunctionSignature(bytes calldata data) internal pure returns (bytes4 functionSelector) {\n        require(data.length >= 4, \"!Data\");\n        return bytes4(data[:4]);\n    }\n\n    function decodeExecuteCalldata(bytes calldata data) internal pure returns (address _target, uint256 _value) {\n        require(data.length >= 4 + 32 + 32, \"!Data\");\n\n        // Decode the address, which is bytes 4 to 35\n        _target = abi.decode(data[4:36], (address));\n\n        // Decode the value, which is bytes 36 to 68\n        _value = abi.decode(data[36:68], (uint256));\n    }\n\n    function decodeExecuteBatchCalldata(\n        bytes calldata data\n    ) internal pure returns (address[] memory _targets, uint256[] memory _values, bytes[] memory _callData) {\n        require(data.length >= 4 + 32 + 32 + 32, \"!Data\");\n\n        (_targets, _values, _callData) = abi.decode(data[4:], (address[], uint256[], bytes[]));\n    }\n\n    /// @notice Validates the signature of a user operation.\n    function _validateSignature(\n        UserOperation calldata userOp,\n        bytes32 userOpHash\n    ) internal virtual override returns (uint256 validationData) {\n        bytes32 hash = userOpHash.toEthSignedMessageHash();\n        address signer = hash.recover(userOp.signature);\n\n        if (!isValidSigner(signer, userOp)) return SIG_VALIDATION_FAILED;\n\n        SignerPermissionsStatic memory permissions = _accountPermissionsStorage().signerPermissions[signer];\n\n        uint48 validAfter = uint48(permissions.startTimestamp);\n        uint48 validUntil = uint48(permissions.endTimestamp);\n\n        return _packValidationData(ValidationData(address(0), validAfter, validUntil));\n    }\n\n    /// @notice Makes the given account an admin.\n    function _setAdmin(address _account, bool _isAdmin) internal virtual override {\n        super._setAdmin(_account, _isAdmin);\n        if (factory.code.length > 0) {\n            if (_isAdmin) {\n                BaseAccountFactory(factory).onSignerAdded(_account, AccountCoreStorage.data().creationSalt);\n            } else {\n                BaseAccountFactory(factory).onSignerRemoved(_account, AccountCoreStorage.data().creationSalt);\n            }\n        }\n    }\n\n    /// @notice Runs after every `changeRole` run.\n    function _afterSignerPermissionsUpdate(SignerPermissionRequest calldata _req) internal virtual override {\n        if (factory.code.length > 0) {\n            BaseAccountFactory(factory).onSignerAdded(_req.signer, AccountCoreStorage.data().creationSalt);\n        }\n    }\n}\n"
      },
      "contracts/prebuilts/account/utils/AccountCoreStorage.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.11;\n\nlibrary AccountCoreStorage {\n    /// @custom:storage-location erc7201:account.core.storage\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"account.core.storage\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 public constant ACCOUNT_CORE_STORAGE_POSITION =\n        0x036f52c1827dab135f7fd44ca0bddde297e2f659c710e0ec53e975f22b548300;\n\n    struct Data {\n        address entrypointOverride;\n        bytes32 creationSalt;\n    }\n\n    function data() internal pure returns (Data storage acountCoreData) {\n        bytes32 position = ACCOUNT_CORE_STORAGE_POSITION;\n        assembly {\n            acountCoreData.slot := position\n        }\n    }\n}\n"
      },
      "contracts/prebuilts/account/utils/AccountExtension.sol": {
        "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity ^0.8.11;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\n// Extensions\nimport \"../../../extension/upgradeable/AccountPermissions.sol\";\nimport \"../../../extension/upgradeable/ContractMetadata.sol\";\nimport \"../../../external-deps/openzeppelin/token/ERC721/utils/ERC721Holder.sol\";\nimport \"../../../external-deps/openzeppelin/token/ERC1155/utils/ERC1155Holder.sol\";\n\n// Utils\nimport \"../../../eip/ERC1271.sol\";\nimport \"../../../external-deps/openzeppelin/utils/cryptography/ECDSA.sol\";\nimport \"../../../external-deps/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport \"./BaseAccountFactory.sol\";\nimport \"./AccountCore.sol\";\nimport \"./AccountCoreStorage.sol\";\n\n//   $$\\     $$\\       $$\\                 $$\\                         $$\\\n//   $$ |    $$ |      \\__|                $$ |                        $$ |\n// $$$$$$\\   $$$$$$$\\  $$\\  $$$$$$\\   $$$$$$$ |$$\\  $$\\  $$\\  $$$$$$\\  $$$$$$$\\\n// \\_$$  _|  $$  __$$\\ $$ |$$  __$$\\ $$  __$$ |$$ | $$ | $$ |$$  __$$\\ $$  __$$\\\n//   $$ |    $$ |  $$ |$$ |$$ |  \\__|$$ /  $$ |$$ | $$ | $$ |$$$$$$$$ |$$ |  $$ |\n//   $$ |$$\\ $$ |  $$ |$$ |$$ |      $$ |  $$ |$$ | $$ | $$ |$$   ____|$$ |  $$ |\n//   \\$$$$  |$$ |  $$ |$$ |$$ |      \\$$$$$$$ |\\$$$$$\\$$$$  |\\$$$$$$$\\ $$$$$$$  |\n//    \\____/ \\__|  \\__|\\__|\\__|       \\_______| \\_____\\____/  \\_______|\\_______/\n\ncontract AccountExtension is ContractMetadata, ERC1271, AccountPermissions, ERC721Holder, ERC1155Holder {\n    using ECDSA for bytes32;\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    bytes32 private constant MSG_TYPEHASH = keccak256(\"AccountMessage(bytes message)\");\n\n    /*///////////////////////////////////////////////////////////////\n                    Constructor, Initializer, Modifiers\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Checks whether the caller is the EntryPoint contract or the admin.\n    modifier onlyAdminOrEntrypoint() virtual {\n        require(\n            msg.sender == address(AccountCore(payable(address(this))).entryPoint()) || isAdmin(msg.sender),\n            \"Account: not admin or EntryPoint.\"\n        );\n        _;\n    }\n\n    // solhint-disable-next-line no-empty-blocks\n    receive() external payable virtual {}\n\n    constructor() EIP712(\"Account\", \"1\") {}\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice See {IERC165-supportsInterface}.\n    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155Receiver) returns (bool) {\n        return\n            interfaceId == type(IERC1155Receiver).interfaceId ||\n            interfaceId == type(IERC721Receiver).interfaceId ||\n            super.supportsInterface(interfaceId);\n    }\n\n    /**\n     *  @notice See EIP-1271\n     *\n     *  @param _hash The original message hash of the data to sign (before mixing this contract's domain separator)\n     *  @param _signature The signature produced on signing the typed data hash (result of `getMessageHash(abi.encode(rawData))`)\n     */\n    function isValidSignature(\n        bytes32 _hash,\n        bytes memory _signature\n    ) public view virtual override returns (bytes4 magicValue) {\n        bytes32 targetDigest = getMessageHash(_hash);\n        address signer = targetDigest.recover(_signature);\n\n        if (isAdmin(signer)) {\n            return MAGICVALUE;\n        }\n\n        address caller = msg.sender;\n        EnumerableSet.AddressSet storage approvedTargets = _accountPermissionsStorage().approvedTargets[signer];\n\n        require(\n            approvedTargets.contains(caller) || (approvedTargets.length() == 1 && approvedTargets.at(0) == address(0)),\n            \"Account: caller not approved target.\"\n        );\n\n        if (isActiveSigner(signer)) {\n            magicValue = MAGICVALUE;\n        }\n    }\n\n    /**\n     * @notice Returns the hash of message that should be signed for EIP1271 verification.\n     * @param _hash The message hash to sign for the EIP-1271 origin verifying contract.\n     * @return messageHash The digest to sign for EIP-1271 verification.\n     */\n    function getMessageHash(bytes32 _hash) public view returns (bytes32) {\n        bytes32 messageHash = keccak256(abi.encode(_hash));\n        bytes32 typedDataHash = keccak256(abi.encode(MSG_TYPEHASH, messageHash));\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", _domainSeparatorV4(), typedDataHash));\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Executes a transaction (called directly from an admin, or by entryPoint)\n    function execute(address _target, uint256 _value, bytes calldata _calldata) external virtual onlyAdminOrEntrypoint {\n        _registerOnFactory();\n        _call(_target, _value, _calldata);\n    }\n\n    /// @notice Executes a sequence transaction (called directly from an admin, or by entryPoint)\n    function executeBatch(\n        address[] calldata _target,\n        uint256[] calldata _value,\n        bytes[] calldata _calldata\n    ) external virtual onlyAdminOrEntrypoint {\n        _registerOnFactory();\n        require(_target.length == _calldata.length && _target.length == _value.length, \"Account: wrong array lengths.\");\n        for (uint256 i = 0; i < _target.length; i++) {\n            _call(_target[i], _value[i], _calldata[i]);\n        }\n    }\n\n    /// @notice Deposit funds for this account in Entrypoint.\n    function addDeposit() public payable {\n        AccountCore(payable(address(this))).entryPoint().depositTo{ value: msg.value }(address(this));\n    }\n\n    /// @notice Withdraw funds for this account from Entrypoint.\n    function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public {\n        _onlyAdmin();\n        AccountCore(payable(address(this))).entryPoint().withdrawTo(withdrawAddress, amount);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                        Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Registers the account on the factory if it hasn't been registered yet.\n    function _registerOnFactory() internal virtual {\n        address factory = AccountCore(payable(address(this))).factory();\n        BaseAccountFactory factoryContract = BaseAccountFactory(factory);\n        if (!factoryContract.isRegistered(address(this))) {\n            factoryContract.onRegister(AccountCoreStorage.data().creationSalt);\n        }\n    }\n\n    /// @dev Calls a target contract and reverts if it fails.\n    function _call(address _target, uint256 value, bytes memory _calldata) internal returns (bytes memory result) {\n        bool success;\n        (success, result) = _target.call{ value: value }(_calldata);\n        if (!success) {\n            assembly {\n                revert(add(result, 32), mload(result))\n            }\n        }\n    }\n\n    /// @dev Returns whether contract metadata can be set in the given execution context.\n    function _canSetContractURI() internal view virtual override returns (bool) {\n        return isAdmin(msg.sender) || msg.sender == address(this);\n    }\n\n    function _afterSignerPermissionsUpdate(SignerPermissionRequest calldata _req) internal virtual override {}\n}\n"
      },
      "contracts/prebuilts/account/utils/BaseAccount.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interface/IAccount.sol\";\nimport \"../interface/IEntrypoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface  - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n    using UserOperationLib for UserOperation;\n\n    //return value in case of signature failure, with no time-range.\n    // equivalent to _packValidationData(true,0,0);\n    uint256 internal constant SIG_VALIDATION_FAILED = 1;\n\n    /**\n     * Return the account nonce.\n     * This method returns the next sequential nonce.\n     * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n     */\n    function getNonce() public view virtual returns (uint256) {\n        return entryPoint().getNonce(address(this), 0);\n    }\n\n    /**\n     * return the entryPoint used by this account.\n     * subclass should return the current entryPoint used by this account.\n     */\n    function entryPoint() public view virtual returns (IEntryPoint);\n\n    /**\n     * Validate user's signature and nonce.\n     * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n     */\n    function validateUserOp(\n        UserOperation calldata userOp,\n        bytes32 userOpHash,\n        uint256 missingAccountFunds\n    ) external virtual override returns (uint256 validationData) {\n        _requireFromEntryPoint();\n        validationData = _validateSignature(userOp, userOpHash);\n        _validateNonce(userOp.nonce);\n        _payPrefund(missingAccountFunds);\n    }\n\n    /**\n     * ensure the request comes from the known entrypoint.\n     */\n    function _requireFromEntryPoint() internal view virtual {\n        require(msg.sender == address(entryPoint()), \"account: not from EntryPoint\");\n    }\n\n    /**\n     * validate the signature is valid for this message.\n     * @param userOp validate the userOp.signature field\n     * @param userOpHash convenient field: the hash of the request, to check the signature against\n     *          (also hashes the entrypoint and chain id)\n     * @return validationData signature and time-range of this operation\n     *      <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n     *         otherwise, an address of an \"authorizer\" contract.\n     *      <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n     *      <6-byte> validAfter - first timestamp this operation is valid\n     *      If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n     *      Note that the validation code cannot use block.timestamp (or block.number) directly.\n     */\n    function _validateSignature(\n        UserOperation calldata userOp,\n        bytes32 userOpHash\n    ) internal virtual returns (uint256 validationData);\n\n    /**\n     * Validate the nonce of the UserOperation.\n     * This method may validate the nonce requirement of this account.\n     * e.g.\n     * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n     *      `require(nonce < type(uint64).max)`\n     * For a hypothetical account that *requires* the nonce to be out-of-order:\n     *      `require(nonce & type(uint64).max == 0)`\n     *\n     * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n     * action is needed by the account itself.\n     *\n     * @param nonce to validate\n     *\n     * solhint-disable-next-line no-empty-blocks\n     */\n    function _validateNonce(uint256 nonce) internal view virtual {}\n\n    /**\n     * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n     * subclass MAY override this method for better funds management\n     * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n     * it will not be required to send again)\n     * @param missingAccountFunds the minimum value this method should send the entrypoint.\n     *  this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n     */\n    function _payPrefund(uint256 missingAccountFunds) internal virtual {\n        if (missingAccountFunds != 0) {\n            (bool success, ) = payable(msg.sender).call{ value: missingAccountFunds, gas: type(uint256).max }(\"\");\n            (success);\n            //ignore failure (its EntryPoint's job to verify, not account.)\n        }\n    }\n}\n"
      },
      "contracts/prebuilts/account/utils/BaseAccountFactory.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// Utils\nimport \"../../../extension/Multicall.sol\";\nimport \"../../../external-deps/openzeppelin/proxy/Clones.sol\";\nimport \"../../../external-deps/openzeppelin/utils/structs/EnumerableSet.sol\";\nimport \"../utils/BaseAccount.sol\";\nimport \"../../../extension/interface/IAccountPermissions.sol\";\nimport \"../../../lib/BytesLib.sol\";\n\n// Interface\nimport \"../interface/IEntrypoint.sol\";\nimport \"../interface/IAccountFactory.sol\";\n\n//   $$\\     $$\\       $$\\                 $$\\                         $$\\\n//   $$ |    $$ |      \\__|                $$ |                        $$ |\n// $$$$$$\\   $$$$$$$\\  $$\\  $$$$$$\\   $$$$$$$ |$$\\  $$\\  $$\\  $$$$$$\\  $$$$$$$\\\n// \\_$$  _|  $$  __$$\\ $$ |$$  __$$\\ $$  __$$ |$$ | $$ | $$ |$$  __$$\\ $$  __$$\\\n//   $$ |    $$ |  $$ |$$ |$$ |  \\__|$$ /  $$ |$$ | $$ | $$ |$$$$$$$$ |$$ |  $$ |\n//   $$ |$$\\ $$ |  $$ |$$ |$$ |      $$ |  $$ |$$ | $$ | $$ |$$   ____|$$ |  $$ |\n//   \\$$$$  |$$ |  $$ |$$ |$$ |      \\$$$$$$$ |\\$$$$$\\$$$$  |\\$$$$$$$\\ $$$$$$$  |\n//    \\____/ \\__|  \\__|\\__|\\__|       \\_______| \\_____\\____/  \\_______|\\_______/\n\nabstract contract BaseAccountFactory is IAccountFactory, Multicall {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /*///////////////////////////////////////////////////////////////\n                                State\n    //////////////////////////////////////////////////////////////*/\n\n    address public immutable accountImplementation;\n    address public immutable entrypoint;\n\n    EnumerableSet.AddressSet private allAccounts;\n    mapping(address => EnumerableSet.AddressSet) internal accountsOfSigner;\n\n    /*///////////////////////////////////////////////////////////////\n                            Constructor\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(address _accountImpl, address _entrypoint) {\n        accountImplementation = _accountImpl;\n        entrypoint = _entrypoint;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                        External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Deploys a new Account for admin.\n    function createAccount(address _admin, bytes calldata _data) external virtual override returns (address) {\n        address impl = accountImplementation;\n        bytes32 salt = _generateSalt(_admin, _data);\n        address account = Clones.predictDeterministicAddress(impl, salt);\n\n        if (account.code.length > 0) {\n            return account;\n        }\n\n        account = Clones.cloneDeterministic(impl, salt);\n\n        if (msg.sender != entrypoint) {\n            require(allAccounts.add(account), \"AccountFactory: account already registered\");\n        }\n\n        _initializeAccount(account, _admin, _data);\n\n        emit AccountCreated(account, _admin);\n\n        return account;\n    }\n\n    /// @notice Callback function for an Account to register itself on the factory.\n    function onRegister(bytes32 _salt) external {\n        address account = msg.sender;\n        require(_isAccountOfFactory(account, _salt), \"AccountFactory: not an account.\");\n\n        require(allAccounts.add(account), \"AccountFactory: account already registered\");\n    }\n\n    function onSignerAdded(address _signer, bytes32 _salt) external {\n        address account = msg.sender;\n        require(_isAccountOfFactory(account, _salt), \"AccountFactory: not an account.\");\n\n        bool isNewSigner = accountsOfSigner[_signer].add(account);\n\n        if (isNewSigner) {\n            emit SignerAdded(account, _signer);\n        }\n    }\n\n    /// @notice Callback function for an Account to un-register its signers.\n    function onSignerRemoved(address _signer, bytes32 _salt) external {\n        address account = msg.sender;\n        require(_isAccountOfFactory(account, _salt), \"AccountFactory: not an account.\");\n\n        bool isAccount = accountsOfSigner[_signer].remove(account);\n\n        if (isAccount) {\n            emit SignerRemoved(account, _signer);\n        }\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns whether an account is registered on this factory.\n    function isRegistered(address _account) external view returns (bool) {\n        return allAccounts.contains(_account);\n    }\n\n    /// @notice Returns the total number of accounts.\n    function totalAccounts() external view returns (uint256) {\n        return allAccounts.length();\n    }\n\n    /// @notice Returns all accounts between the given indices.\n    function getAccounts(uint256 _start, uint256 _end) external view returns (address[] memory accounts) {\n        require(_start < _end && _end <= allAccounts.length(), \"BaseAccountFactory: invalid indices\");\n\n        uint256 len = _end - _start;\n        accounts = new address[](_end - _start);\n\n        for (uint256 i = 0; i < len; i += 1) {\n            accounts[i] = allAccounts.at(i + _start);\n        }\n    }\n\n    /// @notice Returns all accounts created on the factory.\n    function getAllAccounts() external view returns (address[] memory) {\n        return allAccounts.values();\n    }\n\n    /// @notice Returns the address of an Account that would be deployed with the given admin signer.\n    function getAddress(address _adminSigner, bytes calldata _data) public view returns (address) {\n        bytes32 salt = _generateSalt(_adminSigner, _data);\n        return Clones.predictDeterministicAddress(accountImplementation, salt);\n    }\n\n    /// @notice Returns all accounts that the given address is a signer of.\n    function getAccountsOfSigner(address signer) external view returns (address[] memory accounts) {\n        return accountsOfSigner[signer].values();\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Returns whether the caller is an account deployed by this factory.\n    function _isAccountOfFactory(address _account, bytes32 _salt) internal view virtual returns (bool) {\n        address predicted = Clones.predictDeterministicAddress(accountImplementation, _salt);\n        return _account == predicted;\n    }\n\n    function _getImplementation(address cloneAddress) internal view returns (address) {\n        bytes memory code = cloneAddress.code;\n        return BytesLib.toAddress(code, 10);\n    }\n\n    /// @dev Returns the salt used when deploying an Account.\n    function _generateSalt(address _admin, bytes memory _data) internal view virtual returns (bytes32) {\n        return keccak256(abi.encode(_admin, _data));\n    }\n\n    /// @dev Called in `createAccount`. Initializes the account contract created in `createAccount`.\n    function _initializeAccount(address _account, address _admin, bytes calldata _data) internal virtual;\n}\n"
      },
      "contracts/prebuilts/account/utils/Helpers.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n/* solhint-disable func-visibility */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n *              address(1) - the account failed to validate the signature.\n *              otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\nstruct ValidationData {\n    address aggregator;\n    uint48 validAfter;\n    uint48 validUntil;\n}\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\nfunction _parseValidationData(uint256 validationData) pure returns (ValidationData memory data) {\n    address aggregator = address(uint160(validationData));\n    uint48 validUntil = uint48(validationData >> 160);\n    if (validUntil == 0) {\n        validUntil = type(uint48).max;\n    }\n    uint48 validAfter = uint48(validationData >> (48 + 160));\n    return ValidationData(aggregator, validAfter, validUntil);\n}\n\n// intersect account and paymaster ranges.\nfunction _intersectTimeRange(\n    uint256 validationData,\n    uint256 paymasterValidationData\n) pure returns (ValidationData memory) {\n    ValidationData memory accountValidationData = _parseValidationData(validationData);\n    ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n    address aggregator = accountValidationData.aggregator;\n    if (aggregator == address(0)) {\n        aggregator = pmValidationData.aggregator;\n    }\n    uint48 validAfter = accountValidationData.validAfter;\n    uint48 validUntil = accountValidationData.validUntil;\n    uint48 pmValidAfter = pmValidationData.validAfter;\n    uint48 pmValidUntil = pmValidationData.validUntil;\n\n    if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n    if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n    return ValidationData(aggregator, validAfter, validUntil);\n}\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\nfunction _packValidationData(ValidationData memory data) pure returns (uint256) {\n    return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n}\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\nfunction _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n    return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n}\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\nfunction calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n    assembly {\n        let mem := mload(0x40)\n        let len := data.length\n        calldatacopy(mem, data.offset, len)\n        ret := keccak256(mem, len)\n    }\n}\n"
      },
      "contracts/prebuilts/account/utils/UserOperation.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport { calldataKeccak } from \"./Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\nstruct UserOperation {\n    address sender;\n    uint256 nonce;\n    bytes initCode;\n    bytes callData;\n    uint256 callGasLimit;\n    uint256 verificationGasLimit;\n    uint256 preVerificationGas;\n    uint256 maxFeePerGas;\n    uint256 maxPriorityFeePerGas;\n    bytes paymasterAndData;\n    bytes signature;\n}\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n    function getSender(UserOperation calldata userOp) internal pure returns (address) {\n        address data;\n        //read sender from userOp, which is first userOp member (saves 800 gas...)\n        assembly {\n            data := calldataload(userOp)\n        }\n        return address(uint160(data));\n    }\n\n    //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n    // pay above what he signed for.\n    function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n        unchecked {\n            uint256 maxFeePerGas = userOp.maxFeePerGas;\n            uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n            if (maxFeePerGas == maxPriorityFeePerGas) {\n                //legacy mode (for networks that don't support basefee opcode)\n                return maxFeePerGas;\n            }\n            return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n        }\n    }\n\n    function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n        address sender = getSender(userOp);\n        uint256 nonce = userOp.nonce;\n        bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n        bytes32 hashCallData = calldataKeccak(userOp.callData);\n        uint256 callGasLimit = userOp.callGasLimit;\n        uint256 verificationGasLimit = userOp.verificationGasLimit;\n        uint256 preVerificationGas = userOp.preVerificationGas;\n        uint256 maxFeePerGas = userOp.maxFeePerGas;\n        uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n        bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n        return\n            abi.encode(\n                sender,\n                nonce,\n                hashInitCode,\n                hashCallData,\n                callGasLimit,\n                verificationGasLimit,\n                preVerificationGas,\n                maxFeePerGas,\n                maxPriorityFeePerGas,\n                hashPaymasterAndData\n            );\n    }\n\n    function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n        return keccak256(pack(userOp));\n    }\n\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n}\n"
      },
      "lib/dynamic-contracts/lib/sstore2/contracts/SSTORE2.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./utils/Bytecode.sol\";\n\n/**\n  @title A key-value storage with auto-generated keys for storing chunks of data with a lower write & read cost.\n  @author Agustin Aguilar <aa@horizon.io>\n\n  Readme: https://github.com/0xsequence/sstore2#readme\n*/\nlibrary SSTORE2 {\n  error WriteError();\n\n  /**\n    @notice Stores `_data` and returns `pointer` as key for later retrieval\n    @dev The pointer is a contract address with `_data` as code\n    @param _data to be written\n    @return pointer Pointer to the written `_data`\n  */\n  function write(bytes memory _data) internal returns (address pointer) {\n    // Append 00 to _data so contract can't be called\n    // Build init code\n    bytes memory code = Bytecode.creationCodeFor(\n      abi.encodePacked(\n        hex'00',\n        _data\n      )\n    );\n\n    // Deploy contract using create\n    assembly { pointer := create(0, add(code, 32), mload(code)) }\n\n    // Address MUST be non-zero\n    if (pointer == address(0)) revert WriteError();\n  }\n\n  /**\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \n    @dev The function is intended for reading pointers generated by `write`\n    @param _pointer to be read\n    @return data read from `_pointer` contract\n  */\n  function read(address _pointer) internal view returns (bytes memory) {\n    return Bytecode.codeAt(_pointer, 1, type(uint256).max);\n  }\n\n  /**\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \n    @dev The function is intended for reading pointers generated by `write`\n    @param _pointer to be read\n    @param _start number of bytes to skip\n    @return data read from `_pointer` contract\n  */\n  function read(address _pointer, uint256 _start) internal view returns (bytes memory) {\n    return Bytecode.codeAt(_pointer, _start + 1, type(uint256).max);\n  }\n\n  /**\n    @notice Reads the contents of the `_pointer` code as data, skips the first byte \n    @dev The function is intended for reading pointers generated by `write`\n    @param _pointer to be read\n    @param _start number of bytes to skip\n    @param _end index before which to end extraction\n    @return data read from `_pointer` contract\n  */\n  function read(address _pointer, uint256 _start, uint256 _end) internal view returns (bytes memory) {\n    return Bytecode.codeAt(_pointer, _start + 1, _end + 1);\n  }\n}\n"
      },
      "lib/dynamic-contracts/lib/sstore2/contracts/utils/Bytecode.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n\nlibrary Bytecode {\n  error InvalidCodeAtRange(uint256 _size, uint256 _start, uint256 _end);\n\n  /**\n    @notice Generate a creation code that results on a contract with `_code` as bytecode\n    @param _code The returning value of the resulting `creationCode`\n    @return creationCode (constructor) for new contract\n  */\n  function creationCodeFor(bytes memory _code) internal pure returns (bytes memory) {\n    /*\n      0x00    0x63         0x63XXXXXX  PUSH4 _code.length  size\n      0x01    0x80         0x80        DUP1                size size\n      0x02    0x60         0x600e      PUSH1 14            14 size size\n      0x03    0x60         0x6000      PUSH1 00            0 14 size size\n      0x04    0x39         0x39        CODECOPY            size\n      0x05    0x60         0x6000      PUSH1 00            0 size\n      0x06    0xf3         0xf3        RETURN\n      <CODE>\n    */\n\n    return abi.encodePacked(\n      hex\"63\",\n      uint32(_code.length),\n      hex\"80_60_0E_60_00_39_60_00_F3\",\n      _code\n    );\n  }\n\n  /**\n    @notice Returns the size of the code on a given address\n    @param _addr Address that may or may not contain code\n    @return size of the code on the given `_addr`\n  */\n  function codeSize(address _addr) internal view returns (uint256 size) {\n    assembly { size := extcodesize(_addr) }\n  }\n\n  /**\n    @notice Returns the code of a given address\n    @dev It will fail if `_end < _start`\n    @param _addr Address that may or may not contain code\n    @param _start number of bytes of code to skip on read\n    @param _end index before which to end extraction\n    @return oCode read from `_addr` deployed bytecode\n\n    Forked from: https://gist.github.com/KardanovIR/fe98661df9338c842b4a30306d507fbd\n  */\n  function codeAt(address _addr, uint256 _start, uint256 _end) internal view returns (bytes memory oCode) {\n    uint256 csize = codeSize(_addr);\n    if (csize == 0) return bytes(\"\");\n\n    if (_start > csize) return bytes(\"\");\n    if (_end < _start) revert InvalidCodeAtRange(csize, _start, _end); \n\n    unchecked {\n      uint256 reqSize = _end - _start;\n      uint256 maxSize = csize - _start;\n\n      uint256 size = maxSize < reqSize ? maxSize : reqSize;\n\n      assembly {\n        // allocate output byte array - this could also be done without assembly\n        // by using o_code = new bytes(size)\n        oCode := mload(0x40)\n        // new \"memory end\" including padding\n        mstore(0x40, add(oCode, and(add(add(size, 0x20), 0x1f), not(0x1f))))\n        // store length in memory\n        mstore(oCode, size)\n        // actually retrieve the code, this needs assembly\n        extcodecopy(_addr, add(oCode, 0x20), _start, size)\n      }\n    }\n  }\n}\n"
      },
      "lib/dynamic-contracts/src/core/Router.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interface/IRouter.sol\";\n\n/// @title ERC-7504 Dynamic Contracts: Router.\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Routes an incoming call to an appropriate implementation address.\n\nabstract contract Router is IRouter {\n\n    /**\n\t *\t@notice delegateCalls the appropriate implementation address for the given incoming function call.\n\t *\t@dev The implementation address to delegateCall MUST be retrieved from calling `getImplementationForFunction` with the\n     *       incoming call's function selector.\n\t */\n    fallback() external payable virtual {\n        if(msg.data.length == 0) return;\n        \n        address implementation = getImplementationForFunction(msg.sig);\n        require(implementation != address(0), \"Router: function does not exist.\");\n        _delegate(implementation);\n    }\n\n    /// @dev delegateCalls an `implementation` smart contract.\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n\t *\t@notice Returns the implementation address to delegateCall for the given function selector.\n\t *\t@param _functionSelector The function selector to get the implementation address for.\n\t *\t@return implementation The implementation address to delegateCall for the given function selector.\n\t */\n    function getImplementationForFunction(bytes4 _functionSelector) public view virtual returns (address implementation);\n}"
      },
      "lib/dynamic-contracts/src/interface/IExtension.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n\n/// @title IExtension\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Provides an `Extension` abstraction for a router's implementation contracts.\n\ninterface IExtension {\n    /*///////////////////////////////////////////////////////////////\n                                Structs\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice An interface to describe an extension's metadata.\n     *\n     *  @param name             The unique name of the extension.\n     *  @param metadataURI      The URI where the metadata for the extension lives.\n     *  @param implementation   The implementation smart contract address of the extension.\n     */\n    struct ExtensionMetadata {\n        string name;\n        string metadataURI;\n        address implementation;\n    }\n\n    /**\n     *  @notice An interface to describe an extension's function.\n     *\n     *  @param functionSelector    The 4 byte selector of the function.\n     *  @param functionSignature   Function signature as a string. E.g. \"transfer(address,address,uint256)\"\n     */\n    struct ExtensionFunction {\n        bytes4 functionSelector;\n        string functionSignature;\n    }\n\n    /**\n     *  @notice An interface to describe an extension.\n     *\n     *  @param metadata     The extension's metadata; it's name, metadata URI and implementation contract address.\n     *  @param functions    The functions that belong to the extension.\n     */\n    struct Extension {\n        ExtensionMetadata metadata;\n        ExtensionFunction[] functions;\n    }\n}\n"
      },
      "lib/dynamic-contracts/src/interface/IExtensionManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IExtension.sol\";\n\n/// @title IExtensionManager\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Defined storage and API for managing a router's extensions.\n\ninterface IExtensionManager is IExtension {\n\n    /*///////////////////////////////////////////////////////////////\n                                Events\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Emitted when a extension is added.\n    event ExtensionAdded(string indexed name, address indexed implementation, Extension extension);\n\n    /// @dev Emitted when a extension is replaced.\n    event ExtensionReplaced(string indexed name, address indexed implementation, Extension extension);\n\n    /// @dev Emitted when a extension is removed.\n    event ExtensionRemoved(string indexed name, Extension extension);\n\n    /// @dev Emitted when a function is enabled i.e. made callable.\n    event FunctionEnabled(string indexed name, bytes4 indexed functionSelector, ExtensionFunction extFunction, ExtensionMetadata extMetadata);\n\n    /// @dev Emitted when a function is disabled i.e. made un-callable.\n    event FunctionDisabled(string indexed name, bytes4 indexed functionSelector, ExtensionMetadata extMetadata);\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice Add a new extension to the router.\n     *  @param extension The extension to add.\n     */\n    function addExtension(Extension memory extension) external;\n\n    /**\n     *  @notice Fully replace an existing extension of the router.\n     *  @dev The extension with name `extension.name` is the extension being replaced.\n     *  @param extension The extension to replace or overwrite.\n     */\n    function replaceExtension(Extension memory extension) external;\n\n    /**\n     *  @notice Remove an existing extension from the router.\n     *  @param extensionName The name of the extension to remove.\n     */\n    function removeExtension(string memory extensionName) external;\n\n    /**\n     *  @notice Enables a single function in an existing extension.\n     *  @dev Makes the given function callable on the router.\n     *\n     *  @param extensionName The name of the extension to which `extFunction` belongs.\n     *  @param extFunction The function to enable.\n     */\n    function enableFunctionInExtension(string memory extensionName, ExtensionFunction memory extFunction) external;\n    \n    /**\n     *  @notice Disables a single function in an Extension.\n     *\n     *  @param extensionName The name of the extension to which the function of `functionSelector` belongs.\n     *  @param functionSelector The function to disable.\n     */\n    function disableFunctionInExtension(string memory extensionName, bytes4 functionSelector) external;\n}"
      },
      "lib/dynamic-contracts/src/interface/IRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title ERC-7504 Dynamic Contracts: IRouter.\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Routes an incoming call to an appropriate implementation address.\n/// @dev Fallback function delegateCalls `getImplementationForFunction(msg.sig)` for a given incoming call.\n/// NOTE: The ERC-165 identifier for this interface is 0xce0b6013.\n\ninterface IRouter {\n\n\t/**\n\t *\t@notice delegateCalls the appropriate implementation address for the given incoming function call.\n\t *\t@dev The implementation address to delegateCall MUST be retrieved from calling `getImplementationForFunction` with the\n     *       incoming call's function selector.\n\t */\n\tfallback() external payable;\n\n\t/*///////////////////////////////////////////////////////////////\n                            View Functions\n    //////////////////////////////////////////////////////////////*/\n\n\t/**\n\t *\t@notice Returns the implementation address to delegateCall for the given function selector.\n\t *\t@param _functionSelector The function selector to get the implementation address for.\n\t *\t@return implementation The implementation address to delegateCall for the given function selector.\n\t */\n    function getImplementationForFunction(bytes4 _functionSelector) external view returns (address implementation);\n}"
      },
      "lib/dynamic-contracts/src/interface/IRouterState.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IExtension.sol\";\n\n/// @title ERC-7504 Dynamic Contracts: IRouterState.\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Defines an API to expose a router's extensions.\n\ninterface IRouterState is IExtension {\n\n    /*///////////////////////////////////////////////////////////////\n                            View Functions\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice Returns all extensions of the Router.\n     *  @return allExtensions An array of all extensions.\n     */\n    function getAllExtensions() external view returns (Extension[] memory allExtensions);\n}"
      },
      "lib/dynamic-contracts/src/interface/IRouterStateGetters.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./IExtension.sol\";\n\n/// @title IRouterStateGetters.\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Helper view functions to inspect a router's state.\n\ninterface IRouterStateGetters is IExtension {\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice Returns the extension metadata for a given function.\n     *  @param functionSelector The function selector to get the extension metadata for.\n     *  @return metadata The extension metadata for a given function.\n     */\n    function getMetadataForFunction(bytes4 functionSelector) external view returns (ExtensionMetadata memory metadata);\n\n    /**\n     *  @notice Returns the extension metadata and functions for a given extension.\n     *  @param extensionName The name of the extension to get the metadata and functions for.\n     *  @return extension The extension metadata and functions for a given extension.\n     */\n    function getExtension(string memory extensionName) external view returns (Extension memory);\n}"
      },
      "lib/dynamic-contracts/src/lib/BaseRouterStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/// @title BaseRouterStorage\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Defined storage for base router\n\nlibrary BaseRouterStorage {\n\n    /// @custom:storage-location erc7201:base.router.storage\n    bytes32 public constant BASE_ROUTER_STORAGE_POSITION = keccak256(abi.encode(uint256(keccak256(\"base.router.storage\")) - 1));\n\n    struct Data {\n        /// @dev Mapping used only for checking default extension validity in constructor.\n        mapping(bytes4 => bool) functionMap;\n        /// @dev Mapping used only for checking default extension validity in constructor.\n        mapping(string => bool) extensionMap;\n    }\n\n    /// @dev Returns access to base router storage.\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = BASE_ROUTER_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}"
      },
      "lib/dynamic-contracts/src/lib/ExtensionManagerStorage.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./StringSet.sol\";\nimport \"../interface/IExtension.sol\";\n\n/// @title IExtensionManagerStorage\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Defined storage for managing a router's extensions.\n\nlibrary ExtensionManagerStorage {\n\n    /// @custom:storage-location erc7201:extension.manager.storage\n    bytes32 public constant EXTENSION_MANAGER_STORAGE_POSITION = keccak256(abi.encode(uint256(keccak256(\"extension.manager.storage\")) - 1));\n\n    struct Data {\n        /// @dev Set of names of all extensions of the router.\n        StringSet.Set extensionNames;\n        /// @dev Mapping from extension name => `Extension` i.e. extension metadata and functions.\n        mapping(string => IExtension.Extension) extensions;\n        /// @dev Mapping from function selector => metadata of the extension the function belongs to.\n        mapping(bytes4 => IExtension.ExtensionMetadata) extensionMetadata;\n    }\n\n    /// @dev Returns access to the extension manager's storage.\n    function data() internal pure returns (Data storage data_) {\n        bytes32 position = EXTENSION_MANAGER_STORAGE_POSITION;\n        assembly {\n            data_.slot := position\n        }\n    }\n}"
      },
      "lib/dynamic-contracts/src/lib/StringSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary StringSet {\n    struct Set {\n        // Storage of set values\n        string[] _values;\n        // Position of the value in the `values` array, plus 1 because index 0\n        // means a value is not in the set.\n        mapping(string => uint256) _indexes;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, string memory value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._indexes[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, string memory value) private returns (bool) {\n        // We read and store the value's index to prevent multiple reads from the same storage slot\n        uint256 valueIndex = set._indexes[value];\n\n        if (valueIndex != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 toDeleteIndex = valueIndex - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (lastIndex != toDeleteIndex) {\n                string memory lastValue = set._values[lastIndex];\n\n                // Move the last value to the index where the value to delete is\n                set._values[toDeleteIndex] = lastValue;\n                // Update the index for the moved value\n                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the index for the deleted slot\n            delete set._indexes[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, string memory value) private view returns (bool) {\n        return set._indexes[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (string memory) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (string[] memory) {\n        return set._values;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Set storage set, string memory value) internal returns (bool) {\n        return _add(set, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Set storage set, string memory value) internal returns (bool) {\n        return _remove(set, value);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Set storage set, string memory value) internal view returns (bool) {\n        return _contains(set, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Set storage set) internal view returns (uint256) {\n        return _length(set);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Set storage set, uint256 index) internal view returns (string memory) {\n        return _at(set, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Set storage set) internal view returns (string[] memory) {\n        return _values(set);\n    }\n}"
      },
      "lib/dynamic-contracts/src/presets/BaseRouter.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport { Router, IRouter } from \"../core/Router.sol\";\nimport { IRouterState } from \"../interface/IRouterState.sol\";\nimport { IRouterStateGetters } from \"../interface/IRouterStateGetters.sol\";\nimport { BaseRouterStorage } from \"../lib/BaseRouterStorage.sol\";\nimport { ExtensionManager } from \"./ExtensionManager.sol\";\nimport { StringSet } from \"../lib/StringSet.sol\";\nimport \"lib/sstore2/contracts/SSTORE2.sol\";\n\n/// @title BaseRouter\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice A router with an API to manage its extensions.\n\nabstract contract BaseRouter is Router, ExtensionManager {\n\n    using StringSet for StringSet.Set;\n\n    /// @notice The address where the router's default extension set is stored.\n    address public immutable defaultExtensions;\n    \n    /// @notice Initialize the Router with a set of default extensions.\n    constructor(Extension[] memory _extensions) {\n        address pointer;\n        if(_extensions.length > 0) {\n            _validateExtensions(_extensions);\n            pointer = SSTORE2.write(abi.encode(_extensions));\n        }\n\n        defaultExtensions = pointer;\n    }\n\n    /// @notice Initialize the Router with a set of default extensions.\n    function __BaseRouter_init() internal {\n        if(defaultExtensions == address(0)) {\n            return;\n        }\n        \n        bytes memory data = SSTORE2.read(defaultExtensions);\n        Extension[] memory defaults = abi.decode(data, (Extension[]));\n\n        // Unchecked since we already validated extensions in constructor.\n        __BaseRouter_init_unchecked(defaults);\n    }\n\n    /// @notice Initializes the Router with a set of extensions.\n    function __BaseRouter_init_checked(Extension[] memory _extensions) internal {\n        _validateExtensions(_extensions);\n        __BaseRouter_init_unchecked(_extensions);\n    }\n\n    /// @notice Initializes the Router with a set of extensions.\n    function __BaseRouter_init_unchecked(Extension[] memory _extensions) internal {\n        for(uint256 i = 0; i < _extensions.length; i += 1) {\n\n            Extension memory extension = _extensions[i];\n            // Store: new extension name.\n            _extensionManagerStorage().extensionNames.add(extension.metadata.name);\n\n            // 1. Store: metadata for extension.\n            _setMetadataForExtension(extension.metadata.name, extension.metadata);\n\n            uint256 len = extension.functions.length;\n            for (uint256 j = 0; j < len; j += 1) {                \n                // 2. Store: name -> extension.functions map\n                _extensionManagerStorage().extensions[extension.metadata.name].functions.push(extension.functions[j]);\n                // 3. Store: metadata for function.\n                _setMetadataForFunction(extension.functions[j].functionSelector, extension.metadata);\n            }\n\n            emit ExtensionAdded(extension.metadata.name, extension.metadata.implementation, extension);\n        }\n    }\n\n    /// @notice Returns the implementation contract address for a given function signature.\n    function getImplementationForFunction(bytes4 _functionSelector) public view virtual override returns (address) {\n        return getMetadataForFunction(_functionSelector).implementation;\n    }\n\n    /// @dev Validates default extensions.\n    function _validateExtensions(Extension[] memory _extensions) internal {  \n        uint256 len = _extensions.length;\n\n        bool isValid = true;\n\n        for (uint256 i = 0; i < len; i += 1) {\n            isValid = _isValidExtension(_extensions[i]);\n            if(!isValid) {\n                break;\n            }\n        }\n        require(isValid, \"BaseRouter: invalid extension.\");\n    }\n\n    function _isValidExtension(Extension memory _extension) internal returns (bool isValid) {\n        isValid  = bytes(_extension.metadata.name).length > 0 // non-empty name\n            && !BaseRouterStorage.data().extensionMap[_extension.metadata.name] // unused name\n            && _extension.metadata.implementation != address(0); // non-empty implementation\n        \n        BaseRouterStorage.data().extensionMap[_extension.metadata.name] = true;\n\n        if(!isValid) {\n            return false;\n        }\n        \n        uint256 len = _extension.functions.length;\n\n        for(uint256 i = 0; i < len; i += 1) {\n\n            if(!isValid) {\n                break;\n            }\n\n            ExtensionFunction memory _extFunction = _extension.functions[i];\n\n            /**\n            *  Note: `bytes4(0)` is the function selector for the `receive` function.\n            *        So, we maintain a special fn selector-signature mismatch check for the `receive` function.\n            **/\n            bool mismatch = false;\n            if(_extFunction.functionSelector == bytes4(0)) {\n                mismatch = keccak256(abi.encode(_extFunction.functionSignature)) != keccak256(abi.encode(\"receive()\"));\n            } else {\n                mismatch = _extFunction.functionSelector !=\n                    bytes4(keccak256(abi.encodePacked(_extFunction.functionSignature)));\n            }\n\n            // No fn signature-selector mismatch and no duplicate function.\n            isValid = !mismatch && !BaseRouterStorage.data().functionMap[_extFunction.functionSelector];\n            \n            BaseRouterStorage.data().functionMap[_extFunction.functionSelector] = true;\n        }\n    }\n}"
      },
      "lib/dynamic-contracts/src/presets/ExtensionManager.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"../interface/IExtensionManager.sol\";\nimport \"../interface/IRouterState.sol\";\nimport \"../interface/IRouterStateGetters.sol\";\nimport \"../lib/ExtensionManagerStorage.sol\";\n\n/// @title ExtensionManager\n/// @author thirdweb (https://github.com/thirdweb-dev/dynamic-contracts)\n/// @notice Defined storage and API for managing a router's extensions.\n\nabstract contract ExtensionManager is IExtensionManager, IRouterState, IRouterStateGetters {\n\n    using StringSet for StringSet.Set;\n\n    /*///////////////////////////////////////////////////////////////\n                            Modifier\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Checks that a call to any external function is authorized.\n    modifier onlyAuthorizedCall() {\n        require(_isAuthorizedCallToUpgrade(), \"ExtensionManager: unauthorized.\");\n        _;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            View functions\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice Returns all extensions of the Router.\n     *  @return allExtensions An array of all extensions.\n     */\n    function getAllExtensions() external view virtual override returns (Extension[] memory allExtensions) {\n\n        string[] memory names = _extensionManagerStorage().extensionNames.values();\n        uint256 len = names.length;\n        \n        allExtensions = new Extension[](len);\n\n        for (uint256 i = 0; i < len; i += 1) {\n            allExtensions[i] = _getExtension(names[i]);\n        }\n    }\n\n    /**\n     *  @notice Returns the extension metadata for a given function.\n     *  @param functionSelector The function selector to get the extension metadata for.\n     *  @return metadata The extension metadata for a given function.\n     */\n    function getMetadataForFunction(bytes4 functionSelector) public view virtual returns (ExtensionMetadata memory) {\n        return _extensionManagerStorage().extensionMetadata[functionSelector];\n    }\n\n    /**\n     *  @notice Returns the extension metadata and functions for a given extension.\n     *  @param extensionName The name of the extension to get the metadata and functions for.\n     *  @return extension The extension metadata and functions for a given extension.\n     */\n    function getExtension(string memory extensionName) public view virtual returns (Extension memory) {\n        return _getExtension(extensionName);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            External functions\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     *  @notice Add a new extension to the router.\n     *  @param _extension The extension to add.\n     */\n    function addExtension(Extension memory _extension) public virtual onlyAuthorizedCall {    \n        _addExtension(_extension);\n    }\n\n    /**\n     *  @notice Fully replace an existing extension of the router.\n     *  @dev The extension with name `extension.name` is the extension being replaced.\n     *  @param _extension The extension to replace or overwrite.\n     */\n    function replaceExtension(Extension memory _extension) public virtual onlyAuthorizedCall {\n        _replaceExtension(_extension);\n    }\n\n    /**\n     *  @notice Remove an existing extension from the router.\n     *  @param _extensionName The name of the extension to remove.\n     */\n    function removeExtension(string memory _extensionName) public virtual onlyAuthorizedCall {\n        _removeExtension(_extensionName);\n    }\n\n    /**\n     *  @notice Enables a single function in an existing extension.\n     *  @dev Makes the given function callable on the router.\n     *\n     *  @param _extensionName The name of the extension to which `extFunction` belongs.\n     *  @param _function The function to enable.\n     */\n    function enableFunctionInExtension(string memory _extensionName, ExtensionFunction memory _function) public virtual onlyAuthorizedCall {\n        _enableFunctionInExtension(_extensionName, _function);\n    }\n\n    /**\n     *  @notice Disables a single function in an Extension.\n     *\n     *  @param _extensionName The name of the extension to which the function of `functionSelector` belongs.\n     *  @param _functionSelector The function to disable.\n     */\n    function disableFunctionInExtension(string memory _extensionName, bytes4 _functionSelector) public virtual onlyAuthorizedCall {\n        _disableFunctionInExtension(_extensionName, _functionSelector);\n    }\n    \n    /*///////////////////////////////////////////////////////////////\n                            Internal functions\n    //////////////////////////////////////////////////////////////*/\n\n    /// @dev Add a new extension to the router.\n    function _addExtension(Extension memory _extension) internal virtual {    \n        // Check: extension namespace must not already exist.\n        // Check: provided extension namespace must not be empty.\n        // Check: provided extension implementation must be non-zero.\n        // Store: new extension name.\n        require(_canAddExtension(_extension), \"ExtensionManager: cannot add extension.\");\n\n        // 1. Store: metadata for extension.\n        _setMetadataForExtension(_extension.metadata.name, _extension.metadata);\n\n        uint256 len = _extension.functions.length;\n        for (uint256 i = 0; i < len; i += 1) {\n            // 2. Store: function for extension.\n            _addToFunctionMap(_extension.metadata.name, _extension.functions[i]);\n            // 3. Store: metadata for function.\n            _setMetadataForFunction(_extension.functions[i].functionSelector, _extension.metadata);\n        }\n\n        emit ExtensionAdded(_extension.metadata.name, _extension.metadata.implementation, _extension);\n    }\n\n    /// @dev Fully replace an existing extension of the router.\n    function _replaceExtension(Extension memory _extension) internal virtual {\n        // Check: extension namespace must already exist.\n        // Check: provided extension implementation must be non-zero.\n        require(_canReplaceExtension(_extension), \"ExtensionManager: cannot replace extension.\");\n        \n        // 1. Store: metadata for extension.\n        _setMetadataForExtension(_extension.metadata.name, _extension.metadata);\n        // 2. Delete: existing extension.functions and metadata for each function.\n        _removeAllFunctionsFromExtension(_extension.metadata.name);\n        \n        uint256 len = _extension.functions.length;\n        for (uint256 i = 0; i < len; i += 1) {\n            // 2. Store: function for extension.\n            _addToFunctionMap(_extension.metadata.name, _extension.functions[i]);\n            // 3. Store: metadata for function.\n            _setMetadataForFunction(_extension.functions[i].functionSelector, _extension.metadata);\n        }\n\n        emit ExtensionReplaced(_extension.metadata.name, _extension.metadata.implementation, _extension);\n    }\n\n    /// @dev Remove an existing extension from the router.\n    function _removeExtension(string memory _extensionName) internal virtual {\n        // Check: extension namespace must already exist.\n        // Delete: extension namespace.\n        require(_canRemoveExtension(_extensionName), \"ExtensionManager: cannot remove extension.\");\n\n        Extension memory extension = _extensionManagerStorage().extensions[_extensionName];\n\n        // 1. Delete: metadata for extension.\n        _deleteMetadataForExtension(_extensionName);\n        // 2. Delete: existing extension.functions and metadata for each function.\n        _removeAllFunctionsFromExtension(_extensionName);\n\n        emit ExtensionRemoved(_extensionName, extension);\n    }\n\n    /// @dev Makes the given function callable on the router.\n    function _enableFunctionInExtension(string memory _extensionName, ExtensionFunction memory _function) internal virtual {\n        // Check: extension namespace must already exist.\n        require(_canEnableFunctionInExtension(_extensionName, _function), \"ExtensionManager: cannot Store: function for extension.\");\n        \n        // 1. Store: function for extension.\n        _addToFunctionMap(_extensionName, _function);\n\n        ExtensionMetadata memory metadata = _extensionManagerStorage().extensions[_extensionName].metadata;\n        // 2. Store: metadata for function.\n        _setMetadataForFunction(_function.functionSelector, metadata);\n\n        emit FunctionEnabled(_extensionName, _function.functionSelector, _function, metadata);\n    }\n\n    /// @dev Disables a single function in an Extension.\n    function _disableFunctionInExtension(string memory _extensionName, bytes4 _functionSelector) public virtual onlyAuthorizedCall {\n        // Check: extension namespace must already exist.\n        // Check: function must be mapped to provided extension.\n        require(_canDisableFunctionInExtension(_extensionName, _functionSelector), \"ExtensionManager: cannot remove function from extension.\");\n    \n        ExtensionMetadata memory extMetadata = _extensionManagerStorage().extensionMetadata[_functionSelector];\n\n        // 1. Delete: function from extension.\n        _deleteFromFunctionMap(_extensionName, _functionSelector);\n        // 2. Delete: metadata for function.\n        _deleteMetadataForFunction(_functionSelector);\n\n        emit FunctionDisabled(_extensionName, _functionSelector, extMetadata);\n    }\n\n    /// @dev Returns the Extension for a given name.\n    function _getExtension(string memory _extensionName) internal view returns (Extension memory) {\n        return _extensionManagerStorage().extensions[_extensionName];\n    }\n\n    /// @dev Sets the ExtensionMetadata for a given extension.\n    function _setMetadataForExtension(string memory _extensionName, ExtensionMetadata memory _metadata) internal {\n        _extensionManagerStorage().extensions[_extensionName].metadata = _metadata;\n    }\n\n    /// @dev Deletes the ExtensionMetadata for a given extension.\n    function _deleteMetadataForExtension(string memory _extensionName) internal {\n        delete _extensionManagerStorage().extensions[_extensionName].metadata;\n    }\n\n    /// @dev Sets the ExtensionMetadata for a given function.\n    function _setMetadataForFunction(bytes4 _functionSelector, ExtensionMetadata memory _metadata) internal {\n        _extensionManagerStorage().extensionMetadata[_functionSelector] = _metadata;\n    }\n\n    /// @dev Deletes the ExtensionMetadata for a given function.\n    function _deleteMetadataForFunction(bytes4 _functionSelector) internal {\n        delete _extensionManagerStorage().extensionMetadata[_functionSelector];\n    }\n\n    /// @dev Adds a function to the function map of an extension.\n    function _addToFunctionMap(string memory _extensionName, ExtensionFunction memory _extFunction) internal virtual {\n        /**\n         *  Note: `bytes4(0)` is the function selector for the `receive` function.\n         *        So, we maintain a special fn selector-signature mismatch check for the `receive` function.\n        **/\n        bool mismatch = false;\n        if(_extFunction.functionSelector == bytes4(0)) {\n            mismatch = keccak256(abi.encode(_extFunction.functionSignature)) != keccak256(abi.encode(\"receive()\"));\n        } else {\n            mismatch = _extFunction.functionSelector !=\n                bytes4(keccak256(abi.encodePacked(_extFunction.functionSignature)));\n        }\n            \n        // Check: function selector and signature must match.\n        require(\n            !mismatch,\n            \"ExtensionManager: fn selector and signature mismatch.\"\n        );\n        // Check: function must not already be mapped to an implementation.\n        require(\n            _extensionManagerStorage().extensionMetadata[_extFunction.functionSelector].implementation == address(0),\n            \"ExtensionManager: function impl already exists.\"\n        );\n\n        // Store: name -> extension.functions map\n        _extensionManagerStorage().extensions[_extensionName].functions.push(_extFunction);\n    }\n\n    /// @dev Deletes a function from an extension's function map.\n    function _deleteFromFunctionMap(string memory _extensionName, bytes4 _functionSelector) internal {\n        ExtensionFunction[] memory extensionFunctions = _extensionManagerStorage().extensions[_extensionName].functions;\n\n        uint256 len = extensionFunctions.length;\n        for (uint256 i = 0; i < len; i += 1) {\n            if(extensionFunctions[i].functionSelector == _functionSelector) {\n\n                // Delete: particular function from name -> extension.functions map\n                _extensionManagerStorage().extensions[_extensionName].functions[i] = _extensionManagerStorage().extensions[_extensionName].functions[len - 1];\n                _extensionManagerStorage().extensions[_extensionName].functions.pop();\n                break;\n            }\n        }\n    }\n\n    /// @dev Removes all functions from an Extension.\n    function _removeAllFunctionsFromExtension(string memory _extensionName) internal {        \n        ExtensionFunction[] memory functions = _extensionManagerStorage().extensions[_extensionName].functions;\n        \n        // Delete: existing name -> extension.functions map\n        delete _extensionManagerStorage().extensions[_extensionName].functions;\n\n        for(uint256 i = 0; i < functions.length; i += 1) {\n            // Delete: metadata for function.\n            _deleteMetadataForFunction(functions[i].functionSelector);\n        }\n    }\n\n    /// @dev Returns whether a new extension can be added in the given execution context.\n    function _canAddExtension(Extension memory _extension) internal virtual returns (bool) {\n        // Check: provided extension namespace must not be empty.\n        require(bytes(_extension.metadata.name).length > 0, \"ExtensionManager: empty name.\");\n        \n        // Check: extension namespace must not already exist.\n        // Store: new extension name.\n        require(_extensionManagerStorage().extensionNames.add(_extension.metadata.name), \"ExtensionManager: extension already exists.\");\n\n        // Check: extension implementation must be non-zero.\n        require(_extension.metadata.implementation != address(0), \"ExtensionManager: adding extension without implementation.\");\n\n        return true;\n    }\n\n    /// @dev Returns whether an extension can be replaced in the given execution context.\n    function _canReplaceExtension(Extension memory _extension) internal virtual returns (bool) {\n        // Check: extension namespace must already exist.\n        require(_extensionManagerStorage().extensionNames.contains(_extension.metadata.name), \"ExtensionManager: extension does not exist.\");\n\n        // Check: extension implementation must be non-zero.\n        require(_extension.metadata.implementation != address(0), \"ExtensionManager: adding extension without implementation.\");\n\n        return true;\n    }\n\n    /// @dev Returns whether an extension can be removed in the given execution context.\n    function _canRemoveExtension(string memory _extensionName) internal virtual returns (bool) {\n        // Check: extension namespace must already exist.\n        // Delete: extension namespace.\n        require(_extensionManagerStorage().extensionNames.remove(_extensionName), \"ExtensionManager: extension does not exist.\");\n\n        return true;\n    }\n\n    /// @dev Returns whether a function can be enabled in an extension in the given execution context.\n    function _canEnableFunctionInExtension(string memory _extensionName, ExtensionFunction memory) internal view virtual returns (bool) {\n        // Check: extension namespace must already exist.\n        require(_extensionManagerStorage().extensionNames.contains(_extensionName), \"ExtensionManager: extension does not exist.\");\n\n        return true;\n    }\n\n    /// @dev Returns whether a function can be disabled in an extension in the given execution context.\n    function _canDisableFunctionInExtension(string memory _extensionName, bytes4 _functionSelector) internal view virtual returns (bool) {\n        // Check: extension namespace must already exist.\n        require(_extensionManagerStorage().extensionNames.contains(_extensionName), \"ExtensionManager: extension does not exist.\");\n        // Check: function must be mapped to provided extension.\n        require(keccak256(abi.encode(_extensionManagerStorage().extensionMetadata[_functionSelector].name)) == keccak256(abi.encode(_extensionName)), \"ExtensionManager: incorrect extension.\");\n\n        return true;\n    }\n\n    \n    /// @dev Returns the ExtensionManager storage.\n    function _extensionManagerStorage() internal pure returns (ExtensionManagerStorage.Data storage data) {\n        data = ExtensionManagerStorage.data();\n    }\n\n    /// @dev To override; returns whether all relevant permission and other checks are met before any upgrade.\n    function _isAuthorizedCallToUpgrade() internal view virtual returns (bool);\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 20
      },
      "evmVersion": "london",
      "remappings": [
        ":@chainlink/=lib/chainlink/",
        ":@ds-test/=lib/ds-test/src/",
        ":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
        ":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
        ":@std/=lib/forge-std/src/",
        ":@thirdweb-dev/dynamic-contracts/=lib/dynamic-contracts/",
        ":ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
        ":ERC721A/=lib/ERC721A/contracts/",
        ":chainlink/=lib/chainlink/contracts/",
        ":contracts/=contracts/",
        ":ds-test/=lib/ds-test/src/",
        ":dynamic-contracts/=lib/dynamic-contracts/src/",
        ":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
        ":erc721a-upgradeable/=lib/ERC721A-Upgradeable/",
        ":erc721a/=lib/ERC721A/",
        ":forge-std/=lib/forge-std/src/",
        ":lib/sstore2/=lib/dynamic-contracts/lib/sstore2/",
        ":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        ":openzeppelin-contracts/=lib/openzeppelin-contracts/",
        ":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
        ":sstore2/=lib/dynamic-contracts/lib/sstore2/contracts/"
      ],
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}