creation_sourcecode: {{
    "language": "Solidity",
    "settings": {
      "viaIR": false,
      "optimizer": {
        "runs": 200,
        "enabled": true
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {},
      "remappings": [
        "@layerzerolabs/=node_modules/@layerzerolabs/",
        "@openzeppelin/=node_modules/@openzeppelin/",
        "@sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "sphinx/=lib/sphinx/"
      ]
    },
    "sources": {
      "node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\npragma solidity ^0.8.20;\n\n/**\n * @dev Standard ERC20 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\n */\ninterface IERC20Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC20InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC20InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     * @param allowance Amount of tokens a `spender` is allowed to operate with.\n     * @param needed Minimum amount required to perform a transfer.\n     */\n    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC20InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\n     * @param spender Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC20InvalidSpender(address spender);\n}\n\n/**\n * @dev Standard ERC721 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\n */\ninterface IERC721Errors {\n    /**\n     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\n     * Used in balance queries.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721InvalidOwner(address owner);\n\n    /**\n     * @dev Indicates a `tokenId` whose `owner` is the zero address.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721NonexistentToken(uint256 tokenId);\n\n    /**\n     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param tokenId Identifier number of a token.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC721InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC721InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC721InsufficientApproval(address operator, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC721InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC721InvalidOperator(address operator);\n}\n\n/**\n * @dev Standard ERC1155 Errors\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\n */\ninterface IERC1155Errors {\n    /**\n     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     * @param balance Current balance for the interacting account.\n     * @param needed Minimum amount required to perform a transfer.\n     * @param tokenId Identifier number of a token.\n     */\n    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\n\n    /**\n     * @dev Indicates a failure with the token `sender`. Used in transfers.\n     * @param sender Address whose tokens are being transferred.\n     */\n    error ERC1155InvalidSender(address sender);\n\n    /**\n     * @dev Indicates a failure with the token `receiver`. Used in transfers.\n     * @param receiver Address to which tokens are being transferred.\n     */\n    error ERC1155InvalidReceiver(address receiver);\n\n    /**\n     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     * @param owner Address of the current owner of a token.\n     */\n    error ERC1155MissingApprovalForAll(address operator, address owner);\n\n    /**\n     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\n     * @param approver Address initiating an approval operation.\n     */\n    error ERC1155InvalidApprover(address approver);\n\n    /**\n     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\n     * @param operator Address that may be allowed to operate on tokens without being their owner.\n     */\n    error ERC1155InvalidOperator(address operator);\n\n    /**\n     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\n     * Used in batch transfers.\n     * @param idsLength Length of the array of token identifiers\n     * @param valuesLength Length of the array of token amounts\n     */\n    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC20Metadata} from \"./extensions/IERC20Metadata.sol\";\nimport {Context} from \"../../utils/Context.sol\";\nimport {IERC20Errors} from \"../../interfaces/draft-IERC6093.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n */\nabstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {\n    mapping(address account => uint256) private _balances;\n\n    mapping(address account => mapping(address spender => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `value`.\n     */\n    function transfer(address to, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 value) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, value);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `value`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `value`.\n     */\n    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, value);\n        _transfer(from, to, value);\n        return true;\n    }\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _transfer(address from, address to, uint256 value) internal {\n        if (from == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        if (to == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(from, to, value);\n    }\n\n    /**\n     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\n     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\n     * this function.\n     *\n     * Emits a {Transfer} event.\n     */\n    function _update(address from, address to, uint256 value) internal virtual {\n        if (from == address(0)) {\n            // Overflow check required: The rest of the code assumes that totalSupply never overflows\n            _totalSupply += value;\n        } else {\n            uint256 fromBalance = _balances[from];\n            if (fromBalance < value) {\n                revert ERC20InsufficientBalance(from, fromBalance, value);\n            }\n            unchecked {\n                // Overflow not possible: value <= fromBalance <= totalSupply.\n                _balances[from] = fromBalance - value;\n            }\n        }\n\n        if (to == address(0)) {\n            unchecked {\n                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\n                _totalSupply -= value;\n            }\n        } else {\n            unchecked {\n                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\n                _balances[to] += value;\n            }\n        }\n\n        emit Transfer(from, to, value);\n    }\n\n    /**\n     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\n     * Relies on the `_update` mechanism\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead.\n     */\n    function _mint(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidReceiver(address(0));\n        }\n        _update(address(0), account, value);\n    }\n\n    /**\n     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\n     * Relies on the `_update` mechanism.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * NOTE: This function is not virtual, {_update} should be overridden instead\n     */\n    function _burn(address account, uint256 value) internal {\n        if (account == address(0)) {\n            revert ERC20InvalidSender(address(0));\n        }\n        _update(account, address(0), value);\n    }\n\n    /**\n     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     *\n     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\n     */\n    function _approve(address owner, address spender, uint256 value) internal {\n        _approve(owner, spender, value, true);\n    }\n\n    /**\n     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\n     *\n     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\n     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\n     * `Approval` event during `transferFrom` operations.\n     *\n     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\n     * true using the following override:\n     * ```\n     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\n     *     super._approve(owner, spender, value, true);\n     * }\n     * ```\n     *\n     * Requirements are the same as {_approve}.\n     */\n    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\n        if (owner == address(0)) {\n            revert ERC20InvalidApprover(address(0));\n        }\n        if (spender == address(0)) {\n            revert ERC20InvalidSpender(address(0));\n        }\n        _allowances[owner][spender] = value;\n        if (emitEvent) {\n            emit Approval(owner, spender, value);\n        }\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `value`.\n     *\n     * Does not update the allowance value in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Does not emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            if (currentAllowance < value) {\n                revert ERC20InsufficientAllowance(spender, currentAllowance, value);\n            }\n            unchecked {\n                _approve(owner, spender, currentAllowance - value, false);\n            }\n        }\n    }\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "node_modules/@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "src/EIP3009.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\nimport { EIP712Domain } from \"./EIP712Domain.sol\";\r\n\r\nimport { SignatureChecker } from \"./utils/SignatureChecker.sol\";\r\nimport { MessageHashUtils } from \"./utils/MessageHashUtils.sol\";\r\n\r\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\n\r\n/**\r\n * @title EIP-3009\r\n * @notice Provide internal implementation for gas-abstracted transfers\r\n * @dev Contracts that inherit from this must wrap these with publicly\r\n * accessible functions, optionally adding modifiers where necessary\r\n */\r\nabstract contract EIP3009 is ERC20, EIP712Domain {\r\n    // keccak256(\"TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\r\n    bytes32 \r\n        public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = 0x7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267;\r\n\r\n    // keccak256(\"ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)\")\r\n    bytes32\r\n        public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = 0xd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8;\r\n\r\n    // keccak256(\"CancelAuthorization(address authorizer,bytes32 nonce)\")\r\n    bytes32\r\n        public constant CANCEL_AUTHORIZATION_TYPEHASH = 0x158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429;\r\n\r\n    /**\r\n     * @dev authorizer address => nonce => bool (true if nonce is used)\r\n     */\r\n    mapping(address => mapping(bytes32 => bool)) private _authorizationStates;\r\n\r\n    event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce);\r\n    event AuthorizationCanceled(address indexed authorizer, bytes32 indexed nonce);\r\n\r\n    /**\r\n     * @notice Returns the state of an authorization\r\n     * @dev Nonces are randomly generated 32-byte data unique to the authorizer's address\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     * @return True if the nonce is used\r\n     */\r\n    function authorizationState(address authorizer, bytes32 nonce) external view returns (bool) {\r\n        return _authorizationStates[authorizer][nonce];\r\n    }\r\n\r\n    /**\r\n     * @notice Execute a transfer with a signed authorization\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function _transferWithAuthorization(\r\n        address from,\r\n        address to,\r\n        uint256 value,\r\n        uint256 validAfter,\r\n        uint256 validBefore,\r\n        bytes32 nonce,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) internal {\r\n        _transferWithAuthorization(\r\n            from,\r\n            to,\r\n            value,\r\n            validAfter,\r\n            validBefore,\r\n            nonce,\r\n            abi.encodePacked(r, s, v)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @notice Execute a transfer with a signed authorization\r\n     * @dev EOA wallet signatures should be packed in the order of r, s, v.\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param signature     Signature byte array produced by an EOA wallet or a contract wallet\r\n     */\r\n    function _transferWithAuthorization(\r\n        address from,\r\n        address to,\r\n        uint256 value,\r\n        uint256 validAfter,\r\n        uint256 validBefore,\r\n        bytes32 nonce,\r\n        bytes memory signature\r\n    ) internal {\r\n        _requireValidAuthorization(from, nonce, validAfter, validBefore);\r\n        _requireValidSignature(\r\n            from,\r\n            keccak256(\r\n                abi.encode(\r\n                    TRANSFER_WITH_AUTHORIZATION_TYPEHASH,\r\n                    from,\r\n                    to,\r\n                    value,\r\n                    validAfter,\r\n                    validBefore,\r\n                    nonce\r\n                )\r\n            ),\r\n            signature\r\n        );\r\n\r\n        _markAuthorizationAsUsed(from, nonce);\r\n        _transfer(from, to, value);\r\n    }\r\n\r\n    /**\r\n     * @notice Receive a transfer with a signed authorization from the payer\r\n     * @dev This has an additional check to ensure that the payee's address\r\n     * matches the caller of this function to prevent front-running attacks.\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function _receiveWithAuthorization(\r\n        address from,\r\n        address to,\r\n        uint256 value,\r\n        uint256 validAfter,\r\n        uint256 validBefore,\r\n        bytes32 nonce,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) internal {\r\n        _receiveWithAuthorization(\r\n            from,\r\n            to,\r\n            value,\r\n            validAfter,\r\n            validBefore,\r\n            nonce,\r\n            abi.encodePacked(r, s, v)\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @notice Receive a transfer with a signed authorization from the payer\r\n     * @dev This has an additional check to ensure that the payee's address\r\n     * matches the caller of this function to prevent front-running attacks.\r\n     * EOA wallet signatures should be packed in the order of r, s, v.\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param signature     Signature byte array produced by an EOA wallet or a contract wallet\r\n     */\r\n    function _receiveWithAuthorization(\r\n        address from,\r\n        address to,\r\n        uint256 value,\r\n        uint256 validAfter,\r\n        uint256 validBefore,\r\n        bytes32 nonce,\r\n        bytes memory signature\r\n    ) internal {\r\n        require(to == msg.sender, \"Caller must be the payee\");\r\n        _requireValidAuthorization(from, nonce, validAfter, validBefore);\r\n        _requireValidSignature(\r\n            from,\r\n            keccak256(\r\n                abi.encode(\r\n                    RECEIVE_WITH_AUTHORIZATION_TYPEHASH,\r\n                    from,\r\n                    to,\r\n                    value,\r\n                    validAfter,\r\n                    validBefore,\r\n                    nonce\r\n                )\r\n            ),\r\n            signature\r\n        );\r\n\r\n        _markAuthorizationAsUsed(from, nonce);\r\n        _transfer(from, to, value);\r\n    }\r\n\r\n    /**\r\n     * @notice Attempt to cancel an authorization\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function _cancelAuthorization(\r\n        address authorizer,\r\n        bytes32 nonce,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) internal {\r\n        \r\n        _cancelAuthorization(authorizer, nonce, abi.encodePacked(r, s, v));\r\n    }\r\n\r\n    /**\r\n     * @notice Attempt to cancel an authorization\r\n     * @dev EOA wallet signatures should be packed in the order of r, s, v.\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     * @param signature     Signature byte array produced by an EOA wallet or a contract wallet\r\n     */\r\n    function _cancelAuthorization(address authorizer, bytes32 nonce, bytes memory signature) internal {\r\n        _requireUnusedAuthorization(authorizer, nonce);\r\n        _requireValidSignature(\r\n            authorizer,\r\n            keccak256(\r\n                abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce)\r\n            ),\r\n            signature\r\n        );\r\n\r\n        _authorizationStates[authorizer][nonce] = true;\r\n        emit AuthorizationCanceled(authorizer, nonce);\r\n    }\r\n\r\n    /**\r\n     * @notice Validates that signature against input data struct\r\n     * @param signer        Signer's address\r\n     * @param dataHash      Hash of encoded data struct\r\n     * @param signature     Signature byte array produced by an EOA wallet or a contract wallet\r\n     */\r\n    function _requireValidSignature(address signer, bytes32 dataHash, bytes memory signature) private view {\r\n        require(\r\n            SignatureChecker.isValidSignatureNow(signer, MessageHashUtils.toTypedDataHash(_domainSeparator(), dataHash), signature), \r\n            \"Invalid signature\");\r\n    }\r\n\r\n    /**\r\n     * @notice Check that an authorization is unused\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     */\r\n    function _requireUnusedAuthorization(address authorizer, bytes32 nonce) private view {\r\n        require(!_authorizationStates[authorizer][nonce], \"Authorization is used or canceled\");\r\n    }\r\n\r\n    /**\r\n     * @notice Check that authorization is valid\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     */\r\n    function _requireValidAuthorization(\r\n        address authorizer,\r\n        bytes32 nonce,\r\n        uint256 validAfter,\r\n        uint256 validBefore\r\n    ) private view {\r\n\r\n        require(block.timestamp > validAfter, \"Authorization is not yet valid\");\r\n        require(block.timestamp < validBefore, \"Authorization is expired\");\r\n        \r\n        _requireUnusedAuthorization(authorizer, nonce);\r\n    }\r\n\r\n    /**\r\n     * @notice Mark an authorization as used\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     */\r\n    function _markAuthorizationAsUsed(address authorizer, bytes32 nonce) private {\r\n        _authorizationStates[authorizer][nonce] = true;\r\n        emit AuthorizationUsed(authorizer, nonce);\r\n    }\r\n}\r\n"
      },
      "src/EIP712Domain.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\n// solhint-disable func-name-mixedcase\r\n\r\n/**\r\n * @title EIP712 Domain\r\n */\r\ncontract EIP712Domain {\r\n    \r\n    bytes32 internal _DOMAIN_SEPARATOR;\r\n\r\n    // to prevent signature replay attacks in the event the chain forks\r\n    // fork chain would have different chain id to original chain\r\n    uint256 internal immutable _DEPLOYMENT_CHAINID;\r\n\r\n    /**\r\n     * @notice Get the EIP712 Domain Separator.\r\n     * @return The bytes32 EIP712 domain separator.\r\n     */\r\n    function DOMAIN_SEPARATOR() external view returns (bytes32) {\r\n        return _domainSeparator();\r\n    }\r\n\r\n    /**\r\n     * @dev Internal method to get the EIP712 Domain Separator.\r\n     * @return The bytes32 EIP712 domain separator.\r\n     */\r\n    function _domainSeparator() internal virtual view returns (bytes32) {\r\n        return _DOMAIN_SEPARATOR;\r\n    }\r\n\r\n}\r\n"
      },
      "src/IERC1271.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\n/**\r\n * @dev Interface of the ERC1271 standard signature validation method for\r\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\r\n */\r\ninterface IERC1271 {\r\n    /**\r\n     * @dev Should return whether the signature provided is valid for the provided data\r\n     * @param hash          Hash of the data to be signed\r\n     * @param signature     Signature byte array associated with the provided data hash\r\n     * @return magicValue   bytes4 magic value 0x1626ba7e when function passes\r\n     */\r\n    function isValidSignature(bytes32 hash, bytes memory signature)\r\n        external\r\n        view\r\n        returns (bytes4 magicValue);\r\n}\r\n"
      },
      "src/MocaToken.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.22;\r\n\r\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\r\nimport { EIP3009 } from \"./EIP3009.sol\";\r\nimport { EIP712 } from \"./utils/EIP712.sol\";\r\n\r\ncontract MocaToken is EIP3009 {\r\n\r\n    string internal constant _version = \"v1\";\r\n\r\n    constructor(string memory name, string memory symbol, address treasury) ERC20(name, symbol) {\r\n        \r\n        _DEPLOYMENT_CHAINID = block.chainid; \r\n        _DOMAIN_SEPARATOR = EIP712.makeDomainSeparator(name, _version);\r\n\r\n        _mint(treasury, (8_888_888_888 * 1e18));\r\n    }\r\n    \r\n\r\n    /*//////////////////////////////////////////////////////////////\r\n                                 EIP721\r\n    //////////////////////////////////////////////////////////////*/\r\n\r\n    function _domainSeparator() internal override view returns (bytes32) {\r\n        return block.chainid == _DEPLOYMENT_CHAINID ? _DOMAIN_SEPARATOR : EIP712.makeDomainSeparator(name(), _version);\r\n    }\r\n\r\n\r\n    /**\r\n     * @notice Fn caller can only burn their own tokens\r\n     * @param amount          Amount of tokens to burn \r\n     */\r\n    function burn(uint256 amount) external {\r\n        _burn(msg.sender, amount);\r\n    }\r\n\r\n    /**\r\n     * @notice Execute a transfer with a signed authorization\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function transferWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external {\r\n        _transferWithAuthorization(\r\n            from,\r\n            to,\r\n            value,\r\n            validAfter,\r\n            validBefore,\r\n            nonce,\r\n            v,\r\n            r,\r\n            s\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @notice Attempt to cancel an authorization\r\n     * @dev Works only if the authorization is not yet used.\r\n     * EOA wallet signatures should be packed in the order of r, s, v.\r\n     * @param authorizer    Authorizer's address\r\n     * @param nonce         Nonce of the authorization\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function cancelAuthorization(address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s) external {\r\n        _cancelAuthorization(authorizer, nonce, v, r, s);\r\n    }\r\n\r\n    /**\r\n     * @notice Receive a transfer with a signed authorization from the payer\r\n     * @dev This has an additional check to ensure that the payee's address\r\n     * matches the caller of this function to prevent front-running attacks.\r\n     * EOA wallet signatures should be packed in the order of r, s, v.\r\n     * @param from          Payer's address (Authorizer)\r\n     * @param to            Payee's address\r\n     * @param value         Amount to be transferred\r\n     * @param validAfter    The time after which this is valid (unix time)\r\n     * @param validBefore   The time before which this is valid (unix time)\r\n     * @param nonce         Unique nonce\r\n     * @param v             v of the signature\r\n     * @param r             r of the signature\r\n     * @param s             s of the signature\r\n     */\r\n    function receiveWithAuthorization(\r\n        address from,\r\n        address to,\r\n        uint256 value,\r\n        uint256 validAfter,\r\n        uint256 validBefore,\r\n        bytes32 nonce,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) external {\r\n\r\n        _receiveWithAuthorization(\r\n            from,\r\n            to,\r\n            value,\r\n            validAfter,\r\n            validBefore,\r\n            nonce,\r\n            v,\r\n            r,\r\n            s\r\n        );\r\n    }\r\n\r\n}\r\n"
      },
      "src/utils/ECRecover.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\n/**\r\n * @title ECRecover\r\n * @notice A library that provides a safe ECDSA recovery function\r\n */\r\nlibrary ECRecover {\r\n    /**\r\n     * @notice Recover signer's address from a signed message\r\n     * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/65e4ffde586ec89af3b7e9140bdc9235d1254853/contracts/cryptography/ECDSA.sol\r\n     * Modifications: Accept v, r, and s as separate arguments\r\n     * @param digest    Keccak-256 hash digest of the signed message\r\n     * @param v         v of the signature\r\n     * @param r         r of the signature\r\n     * @param s         s of the signature\r\n     * @return Signer address\r\n     */\r\n    function recover(\r\n        bytes32 digest,\r\n        uint8 v,\r\n        bytes32 r,\r\n        bytes32 s\r\n    ) internal pure returns (address) {\r\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\r\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\r\n        // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\r\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\r\n        //\r\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\r\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\r\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\r\n        // these malleable signatures as well.\r\n        if (\r\n            uint256(s) >\r\n            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0\r\n        ) {\r\n            revert(\"ECRecover: invalid signature 's' value\");\r\n        }\r\n\r\n        if (v != 27 && v != 28) {\r\n            revert(\"ECRecover: invalid signature 'v' value\");\r\n        }\r\n\r\n        // If the signature is valid (and not malleable), return the signer address\r\n        address signer = ecrecover(digest, v, r, s);\r\n        require(signer != address(0), \"ECRecover: invalid signature\");\r\n\r\n        return signer;\r\n    }\r\n\r\n    /**\r\n     * @notice Recover signer's address from a signed message\r\n     * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/0053ee040a7ff1dbc39691c9e67a69f564930a88/contracts/utils/cryptography/ECDSA.sol\r\n     * @param digest    Keccak-256 hash digest of the signed message\r\n     * @param signature Signature byte array associated with hash\r\n     * @return Signer address\r\n     */\r\n    function recover(bytes32 digest, bytes memory signature)\r\n        internal\r\n        pure\r\n        returns (address)\r\n    {\r\n        require(signature.length == 65, \"ECRecover: invalid signature length\");\r\n\r\n        bytes32 r;\r\n        bytes32 s;\r\n        uint8 v;\r\n\r\n        // ecrecover takes the signature parameters, and the only way to get them\r\n        // currently is to use assembly.\r\n        /// @solidity memory-safe-assembly\r\n        assembly {\r\n            r := mload(add(signature, 0x20))\r\n            s := mload(add(signature, 0x40))\r\n            v := byte(0, mload(add(signature, 0x60)))\r\n        }\r\n        return recover(digest, v, r, s);\r\n    }\r\n}\r\n"
      },
      "src/utils/EIP712.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\n/**\r\n * @title EIP712\r\n * @notice A library that provides EIP712 helper functions\r\n */\r\nlibrary EIP712 {\r\n    /**\r\n     * @notice Make EIP712 domain separator\r\n     * @param name      Contract name\r\n     * @param version   Contract version\r\n     * @param chainId   Blockchain ID\r\n     * @return Domain separator\r\n     */\r\n    function makeDomainSeparator(\r\n        string memory name,\r\n        string memory version,\r\n        uint256 chainId\r\n    ) internal view returns (bytes32) {\r\n        return\r\n            keccak256(\r\n                abi.encode(\r\n                    // keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\")\r\n                    0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\r\n                    keccak256(bytes(name)),\r\n                    keccak256(bytes(version)),\r\n                    chainId,\r\n                    address(this)\r\n                )\r\n            );\r\n    }\r\n\r\n    /**\r\n     * @notice Make EIP712 domain separator\r\n     * @param name      Contract name\r\n     * @param version   Contract version\r\n     * @return Domain separator\r\n     */\r\n    function makeDomainSeparator(string memory name, string memory version)\r\n        internal\r\n        view\r\n        returns (bytes32)\r\n    {\r\n        uint256 chainId;\r\n        assembly {\r\n            chainId := chainid()\r\n        }\r\n        return makeDomainSeparator(name, version, chainId);\r\n    }\r\n}\r\n"
      },
      "src/utils/MessageHashUtils.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\n/**\r\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\r\n *\r\n * The library provides methods for generating a hash of a message that conforms to the\r\n * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\r\n * specifications.\r\n */\r\nlibrary MessageHashUtils {\r\n    /**\r\n     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).\r\n     * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/MessageHashUtils.sol\r\n     *\r\n     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\r\n     * `\\x19\\x01` and hashing the result. It corresponds to the hash signed by the\r\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\r\n     *\r\n     * @param domainSeparator    Domain separator\r\n     * @param structHash         Hashed EIP-712 data struct\r\n     * @return digest            The keccak256 digest of an EIP-712 typed data\r\n     */\r\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash)\r\n        internal\r\n        pure\r\n        returns (bytes32 digest)\r\n    {\r\n        assembly {\r\n            let ptr := mload(0x40)\r\n            mstore(ptr, \"\\x19\\x01\")\r\n            mstore(add(ptr, 0x02), domainSeparator)\r\n            mstore(add(ptr, 0x22), structHash)\r\n            digest := keccak256(ptr, 0x42)\r\n        }\r\n    }\r\n}\r\n"
      },
      "src/utils/SignatureChecker.sol": {
        "content": "// SPDX-License-Identifier: MIT\r\npragma solidity ^0.8.20;\r\n\r\nimport { ECRecover } from \"./ECRecover.sol\";\r\nimport { IERC1271 } from \"./../IERC1271.sol\";\r\n\r\n/**\r\n * @dev Signature verification helper that can be used instead of `ECRecover.recover` to seamlessly support both ECDSA\r\n * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets.\r\n *\r\n * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/SignatureChecker.sol\r\n */\r\nlibrary SignatureChecker {\r\n    /**\r\n     * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the\r\n     * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECRecover.recover`.\r\n     * @param signer        Address of the claimed signer\r\n     * @param digest        Keccak-256 hash digest of the signed message\r\n     * @param signature     Signature byte array associated with hash\r\n     */\r\n    function isValidSignatureNow(address signer, bytes32 digest, bytes memory signature) internal view returns (bool) {\r\n        if (!isContract(signer)) {\r\n            return ECRecover.recover(digest, signature) == signer;\r\n        }\r\n        return isValidERC1271SignatureNow(signer, digest, signature);\r\n    }\r\n\r\n    /**\r\n     * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated\r\n     * against the signer smart contract using ERC1271.\r\n     * @param signer        Address of the claimed signer\r\n     * @param digest        Keccak-256 hash digest of the signed message\r\n     * @param signature     Signature byte array associated with hash\r\n     *\r\n     * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus\r\n     * change through time. It could return true at block N and false at block N+1 (or the opposite).\r\n     */\r\n    function isValidERC1271SignatureNow(address signer, bytes32 digest, bytes memory signature) internal view returns (bool) {\r\n        (bool success, bytes memory result) = signer.staticcall(\r\n            abi.encodeWithSelector(\r\n                IERC1271.isValidSignature.selector,\r\n                digest,\r\n                signature\r\n            )\r\n        );\r\n        return (success && result.length >= 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));\r\n    }\r\n\r\n    /**\r\n     * @dev Checks if the input address is a smart contract.\r\n     */\r\n    function isContract(address addr) internal view returns (bool) {\r\n        uint256 size;\r\n        assembly {\r\n            size := extcodesize(addr)\r\n        }\r\n        return size > 0;\r\n    }\r\n}\r\n"
      }
    }
  }}