{
  "address": "0x55Fa097cA59BAc70C1ba488BEb11A5F6bf7019Eb",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "wrappedNative_",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "backendSigner_",
          "type": "address"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "CallerNotAuthorized",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "DeadlineReached",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidShortString",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "MissingSignature",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "NoCallsProvided",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "SaltAlreadyUsed",
      "type": "error"
    },
    {
      "inputs": [
        {
          "internalType": "string",
          "name": "str",
          "type": "string"
        }
      ],
      "name": "StringTooLong",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "Unauthorized",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAddress",
      "type": "error"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "oldSigner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newSigner",
          "type": "address"
        }
      ],
      "name": "BackendSignerUpdated",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [],
      "name": "EIP712DomainChanged",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "caller",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "callsCount",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "uint256",
          "name": "deadline",
          "type": "uint256"
        },
        {
          "indexed": false,
          "internalType": "bytes32",
          "name": "salt",
          "type": "bytes32"
        }
      ],
      "name": "MulticallExecuted",
      "type": "event"
    },
    {
      "anonymous": false,
      "inputs": [
        {
          "indexed": true,
          "internalType": "address",
          "name": "previousOwner",
          "type": "address"
        },
        {
          "indexed": true,
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "OwnershipTransferred",
      "type": "event"
    },
    {
      "inputs": [],
      "name": "WRAPPED_NATIVE",
      "outputs": [
        {
          "internalType": "contract IWBNB",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IERC20Upgradeable",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "spender",
          "type": "address"
        }
      ],
      "name": "approveMax",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "backendSigner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "eip712Domain",
      "outputs": [
        {
          "internalType": "bytes1",
          "name": "fields",
          "type": "bytes1"
        },
        {
          "internalType": "string",
          "name": "name",
          "type": "string"
        },
        {
          "internalType": "string",
          "name": "version",
          "type": "string"
        },
        {
          "internalType": "uint256",
          "name": "chainId",
          "type": "uint256"
        },
        {
          "internalType": "address",
          "name": "verifyingContract",
          "type": "address"
        },
        {
          "internalType": "bytes32",
          "name": "salt",
          "type": "bytes32"
        },
        {
          "internalType": "uint256[]",
          "name": "extensions",
          "type": "uint256[]"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "target",
          "type": "address"
        },
        {
          "internalType": "bytes",
          "name": "data",
          "type": "bytes"
        }
      ],
      "name": "genericCall",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes[]",
          "name": "calls",
          "type": "bytes[]"
        },
        {
          "internalType": "uint256",
          "name": "deadline",
          "type": "uint256"
        },
        {
          "internalType": "bytes32",
          "name": "salt",
          "type": "bytes32"
        },
        {
          "internalType": "bytes",
          "name": "signature",
          "type": "bytes"
        }
      ],
      "name": "multicall",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "owner",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "renounceOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newSigner",
          "type": "address"
        }
      ],
      "name": "setBackendSigner",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "contract IERC20Upgradeable",
          "name": "token",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "to",
          "type": "address"
        }
      ],
      "name": "sweep",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "newOwner",
          "type": "address"
        }
      ],
      "name": "transferOwnership",
      "outputs": [],
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "bytes32",
          "name": "",
          "type": "bytes32"
        }
      ],
      "name": "usedSalts",
      "outputs": [
        {
          "internalType": "bool",
          "name": "",
          "type": "bool"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      "name": "wrap",
      "outputs": [],
      "stateMutability": "payable",
      "type": "function"
    }
  ],
  "transactionHash": "0xcae52be53fed71bd52a7823c08e712d438ee7852be88b5d735b564d2996ec3eb",
  "receipt": {
    "to": null,
    "from": "0x616574729DF936d26F328a934401983cB189951c",
    "contractAddress": "0x55Fa097cA59BAc70C1ba488BEb11A5F6bf7019Eb",
    "transactionIndex": 0,
    "gasUsed": "1458584",
    "logsBloom": "0x00000000000000000000000000000000000400000000000000800000000000000000000000000000000000000000000000000000000000000000000000080000000000000000004000000000000000000001000000000000000000800000000000000000020000000000000000000800000000000000000000000000000000400400000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0xac5f08293cc04601df33ab76c1eb93d09d13a83fb211fa4b3ca5ba56eed9dea2",
    "transactionHash": "0xcae52be53fed71bd52a7823c08e712d438ee7852be88b5d735b564d2996ec3eb",
    "logs": [
      {
        "transactionIndex": 0,
        "blockNumber": 71460559,
        "transactionHash": "0xcae52be53fed71bd52a7823c08e712d438ee7852be88b5d735b564d2996ec3eb",
        "address": "0x55Fa097cA59BAc70C1ba488BEb11A5F6bf7019Eb",
        "topics": [
          "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0",
          "0x0000000000000000000000000000000000000000000000000000000000000000",
          "0x000000000000000000000000616574729df936d26f328a934401983cb189951c"
        ],
        "data": "0x",
        "logIndex": 0,
        "blockHash": "0xac5f08293cc04601df33ab76c1eb93d09d13a83fb211fa4b3ca5ba56eed9dea2"
      }
    ],
    "blockNumber": 71460559,
    "cumulativeGasUsed": "1458584",
    "status": 1,
    "byzantium": true
  },
  "args": ["0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", "0x58C450312686B17f0A18a1072d091a0891B8b916"],
  "numDeployments": 2,
  "solcInputHash": "5daf1620a8af9648f7f80eb086519ad7",
  "metadata": "{\"compiler\":{\"version\":\"0.8.28+commit.7893614a\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"wrappedNative_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"backendSigner_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"CallerNotAuthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DeadlineReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidShortString\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MissingSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCallsProvided\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SaltAlreadyUsed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"str\",\"type\":\"string\"}],\"name\":\"StringTooLong\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldSigner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newSigner\",\"type\":\"address\"}],\"name\":\"BackendSignerUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"EIP712DomainChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"callsCount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"MulticallExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"WRAPPED_NATIVE\",\"outputs\":[{\"internalType\":\"contract IWBNB\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"approveMax\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"backendSigner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"eip712Domain\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"fields\",\"type\":\"bytes1\"},{\"internalType\":\"string\",\"name\":\"name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"version\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"verifyingContract\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"extensions\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"genericCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"calls\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"multicall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newSigner\",\"type\":\"address\"}],\"name\":\"setBackendSigner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20Upgradeable\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"sweep\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"usedSalts\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"wrap\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus Protocol\",\"custom:security-contact\":\"security@venus.io\",\"details\":\"This contract provides utilities for wrapping native tokens, managing approvals,      and executing arbitrary calls in a single transaction. It supports optional      signature verification using EIP-712 for backend-authorized operations.      All functions except multicall are designed to be called internally via multicall.\",\"errors\":{\"CallerNotAuthorized()\":[{\"details\":\"Only owner or contract itself can call protected functions\"}],\"DeadlineReached()\":[{\"details\":\"Emitted when block.timestamp > deadline in multicall\"}],\"MissingSignature()\":[{\"details\":\"Emitted when signature length is zero but verification is expected\"}],\"NoCallsProvided()\":[{\"details\":\"Emitted when calls array is empty in multicall\"}],\"SaltAlreadyUsed()\":[{\"details\":\"Prevents replay attacks by ensuring each salt is used only once\"}],\"Unauthorized()\":[{\"details\":\"Emitted when recovered signer doesn't match backendSigner\"}],\"ZeroAddress()\":[{\"details\":\"Used in constructor and setBackendSigner validation\"}]},\"events\":{\"BackendSignerUpdated(address,address)\":{\"params\":{\"newSigner\":\"New backend signer address\",\"oldSigner\":\"Previous backend signer address\"}},\"EIP712DomainChanged()\":{\"details\":\"MAY be emitted to signal that the domain could have changed.\"},\"MulticallExecuted(address,uint256,uint256,bytes32)\":{\"params\":{\"caller\":\"Address that initiated the multicall\",\"callsCount\":\"Number of calls executed in the batch\",\"deadline\":\"Deadline timestamp used for the operation\",\"salt\":\"Salt used for replay protection\"}}},\"kind\":\"dev\",\"methods\":{\"approveMax(address,address)\":{\"custom:error\":\"CallerNotAuthorized if caller is not owner or contract itself\",\"custom:security\":\"Grants unlimited approval - ensure spender is trusted\",\"details\":\"Sets approval to type(uint256).max for unlimited spendingUses forceApprove to handle tokens that require 0 approval firstShould only be called via multicall\",\"params\":{\"spender\":\"Address to grant approval to\",\"token\":\"ERC-20 token contract to approve\"}},\"constructor\":{\"custom:error\":\"ZeroAddress if wrappedNative_ is address(0)ZeroAddress if backendSigner_ is address(0)\",\"details\":\"Initializes EIP-712 domain with name \\\"VenusSwap\\\" and version \\\"1\\\"Transfers ownership to msg.senderReverts with ZeroAddress if either parameter is address(0)\",\"params\":{\"backendSigner_\":\"Address authorized to sign multicall operations\",\"wrappedNative_\":\"Address of the wrapped native asset contract\"}},\"eip712Domain()\":{\"details\":\"See {EIP-5267}. _Available since v4.9._\"},\"genericCall(address,bytes)\":{\"custom:error\":\"CallerNotAuthorized if caller is not owner or contract itself\",\"custom:security\":\"Use with extreme caution - can call any contract with any dataEnsure proper validation of target and data in off-chain systems\",\"details\":\"This function can interact with any external contractShould only be called via multicall for safety\",\"params\":{\"data\":\"Encoded function call data\",\"target\":\"Address of the contract to call\"}},\"multicall(bytes[],uint256,bytes32,bytes)\":{\"custom:error\":\"NoCallsProvided if calls array is emptyDeadlineReached if block.timestamp > deadlineSaltAlreadyUsed if salt has been used beforeUnauthorized if signature verification fails\",\"custom:security\":\"Only the contract itself can call wrap, sweep, approveMax, and genericCall\",\"details\":\"All calls are executed atomically - if any call fails, entire transaction revertsCalls must be to functions on this contract (address(this))Signature verification is only performed if signature.length != 0Protected by nonReentrant modifier to prevent reentrancy attacksEmits MulticallExecuted event upon successful execution\",\"params\":{\"calls\":\"Array of encoded function calls to execute on this contract\",\"deadline\":\"Unix timestamp after which the transaction will revert\",\"salt\":\"Unique value to ensure this exact multicall can only be executed once\",\"signature\":\"Optional EIP-712 signature from backend signer (empty bytes to skip verification)\"}},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setBackendSigner(address)\":{\"custom:error\":\"ZeroAddress if newSigner is address(0)Ownable: caller is not the owner (from OpenZeppelin Ownable)\",\"details\":\"Only callable by contract ownerReverts with ZeroAddress if newSigner is address(0)Emits BackendSignerUpdated event\",\"params\":{\"newSigner\":\"New backend signer address\"}},\"sweep(address,address)\":{\"custom:error\":\"CallerNotAuthorized if caller is not owner or contract itself\",\"details\":\"Transfers the entire balance of token held by this contractUses SafeERC20 for safe transfer operationsShould only be called via multicall\",\"params\":{\"to\":\"Recipient address for the swept tokens\",\"token\":\"ERC-20 token contract to sweep\"}},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"wrap(uint256)\":{\"custom:error\":\"CallerNotAuthorized if caller is not owner or contract itself\",\"custom:security\":\"Ensure msg.value matches amount parameter\",\"details\":\"Calls deposit() on WRAPPED_NATIVE contract with msg.valueWrapped tokens remain in this contract until sweptShould only be called via multicall\",\"params\":{\"amount\":\"Amount of native asset to wrap (must match msg.value)\"}}},\"stateVariables\":{\"MULTICALL_TYPEHASH\":{\"details\":\"keccak256(\\\"Multicall(bytes[] calls,uint256 deadline,bytes32 salt)\\\")\"},\"backendSigner\":{\"details\":\"Can be updated by contract owner via setBackendSigner\"},\"usedSalts\":{\"details\":\"Maps salt => bool to prevent reuse of same salt\"}},\"title\":\"SwapHelper\",\"version\":1},\"userdoc\":{\"errors\":{\"CallerNotAuthorized()\":[{\"notice\":\"Error thrown when caller is not authorized\"}],\"DeadlineReached()\":[{\"notice\":\"Error thrown when transaction deadline has passed\"}],\"MissingSignature()\":[{\"notice\":\"Error thrown when signature is missing but required\"}],\"NoCallsProvided()\":[{\"notice\":\"Error thrown when no calls are provided to multicall\"}],\"SaltAlreadyUsed()\":[{\"notice\":\"Error thrown when salt has already been used\"}],\"Unauthorized()\":[{\"notice\":\"Error thrown when signature verification fails\"}],\"ZeroAddress()\":[{\"notice\":\"Error thrown when zero address is provided as parameter\"}]},\"events\":{\"BackendSignerUpdated(address,address)\":{\"notice\":\"Event emitted when backend signer is updated\"},\"MulticallExecuted(address,uint256,uint256,bytes32)\":{\"notice\":\"Event emitted when multicall is successfully executed\"}},\"kind\":\"user\",\"methods\":{\"WRAPPED_NATIVE()\":{\"notice\":\"Wrapped native asset contract (e.g., WBNB, WETH)\"},\"approveMax(address,address)\":{\"notice\":\"Approves maximum amount of an ERC-20 token to a specified spender\"},\"backendSigner()\":{\"notice\":\"Address authorized to sign multicall operations\"},\"constructor\":{\"notice\":\"Constructor\"},\"genericCall(address,bytes)\":{\"notice\":\"Generic call function to execute a call to an arbitrary address\"},\"multicall(bytes[],uint256,bytes32,bytes)\":{\"notice\":\"Multicall function to execute multiple calls in a single transaction\"},\"setBackendSigner(address)\":{\"notice\":\"Updates the backend signer address\"},\"sweep(address,address)\":{\"notice\":\"Sweeps entire balance of an ERC-20 token to a specified address\"},\"usedSalts(bytes32)\":{\"notice\":\"Mapping to track used salts for replay protection\"},\"wrap(uint256)\":{\"notice\":\"Wraps native asset into an ERC-20 wrapped token\"}},\"notice\":\"Helper contract for executing multiple token operations atomically\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SwapHelper/SwapHelper.sol\":\"SwapHelper\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `to`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address to, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `from` to `to` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x0e1f0f5f62f67a881cd1a9597acbc0a5e4071f3c2c10449a183b922ae7272e3f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * ==== Security Considerations\\n *\\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\\n * generally recommended is:\\n *\\n * ```solidity\\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\\n *     doThing(..., value);\\n * }\\n *\\n * function doThing(..., uint256 value) public {\\n *     token.safeTransferFrom(msg.sender, address(this), value);\\n *     ...\\n * }\\n * ```\\n *\\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\\n * {SafeERC20-safeTransferFrom}).\\n *\\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\\n * contracts should have entry points that don't rely on permit.\\n */\\ninterface IERC20PermitUpgradeable {\\n    /**\\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n     * given ``owner``'s signed approval.\\n     *\\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n     * ordering also apply here.\\n     *\\n     * Emits an {Approval} event.\\n     *\\n     * Requirements:\\n     *\\n     * - `spender` cannot be the zero address.\\n     * - `deadline` must be a timestamp in the future.\\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n     * over the EIP712-formatted function arguments.\\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\\n     *\\n     * For more information on the signature format, see the\\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n     * section].\\n     *\\n     * CAUTION: See Security Considerations above.\\n     */\\n    function permit(\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) external;\\n\\n    /**\\n     * @dev Returns the current nonce for `owner`. This value must be\\n     * included whenever a signature is generated for {permit}.\\n     *\\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n     * prevents a signature from being used multiple times.\\n     */\\n    function nonces(address owner) external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n     */\\n    // solhint-disable-next-line func-name-mixedcase\\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x07e881de3b9f6d2c07909f193f24b96c7fe4ea60013260f3f25aecd8bab3c2f8\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\nimport \\\"../extensions/IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20Upgradeable {\\n    using AddressUpgradeable for address;\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    /**\\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n     */\\n    function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        require(\\n            (value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    /**\\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        uint256 oldAllowance = token.allowance(address(this), spender);\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\\n    }\\n\\n    /**\\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful.\\n     */\\n    function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        unchecked {\\n            uint256 oldAllowance = token.allowance(address(this), spender);\\n            require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\\n        }\\n    }\\n\\n    /**\\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n     * to be set to zero before setting it to a non-zero value, such as USDT.\\n     */\\n    function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {\\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\\n\\n        if (!_callOptionalReturnBool(token, approvalCall)) {\\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\\n            _callOptionalReturn(token, approvalCall);\\n        }\\n    }\\n\\n    /**\\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\\n     * Revert on invalid signature.\\n     */\\n    function safePermit(\\n        IERC20PermitUpgradeable token,\\n        address owner,\\n        address spender,\\n        uint256 value,\\n        uint256 deadline,\\n        uint8 v,\\n        bytes32 r,\\n        bytes32 s\\n    ) internal {\\n        uint256 nonceBefore = token.nonces(owner);\\n        token.permit(owner, spender, value, deadline, v, r, s);\\n        uint256 nonceAfter = token.nonces(owner);\\n        require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     *\\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n     */\\n    function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\\n        // and not revert is the subcall reverts.\\n\\n        (bool success, bytes memory returndata) = address(token).call(data);\\n        return\\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));\\n    }\\n}\\n\",\"keccak256\":\"0x23b997be73d3dd46885262704f0f8cfc7273fdadfe303d37969a9561373972b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\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\",\"keccak256\":\"0x9c80f545915582e63fe206c6ce27cbe85a86fc10b9cd2a0e8c9488fb7c2ee422\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n    address private _owner;\\n\\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n    /**\\n     * @dev Initializes the contract setting the deployer as the initial owner.\\n     */\\n    constructor() {\\n        _transferOwnership(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Throws if called by any account other than the owner.\\n     */\\n    modifier onlyOwner() {\\n        _checkOwner();\\n        _;\\n    }\\n\\n    /**\\n     * @dev Returns the address of the current owner.\\n     */\\n    function owner() public view virtual returns (address) {\\n        return _owner;\\n    }\\n\\n    /**\\n     * @dev Throws if the sender is not the owner.\\n     */\\n    function _checkOwner() internal view virtual {\\n        require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n    }\\n\\n    /**\\n     * @dev Leaves the contract without owner. It will not be possible to call\\n     * `onlyOwner` functions. Can only be called by the current owner.\\n     *\\n     * NOTE: Renouncing ownership will leave the contract without an owner,\\n     * thereby disabling any functionality that is only available to the owner.\\n     */\\n    function renounceOwnership() public virtual onlyOwner {\\n        _transferOwnership(address(0));\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Can only be called by the current owner.\\n     */\\n    function transferOwnership(address newOwner) public virtual onlyOwner {\\n        require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n        _transferOwnership(newOwner);\\n    }\\n\\n    /**\\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n     * Internal function without access restriction.\\n     */\\n    function _transferOwnership(address newOwner) internal virtual {\\n        address oldOwner = _owner;\\n        _owner = newOwner;\\n        emit OwnershipTransferred(oldOwner, newOwner);\\n    }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5267.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.0;\\n\\ninterface IERC5267 {\\n    /**\\n     * @dev MAY be emitted to signal that the domain could have changed.\\n     */\\n    event EIP712DomainChanged();\\n\\n    /**\\n     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n     * signature.\\n     */\\n    function eip712Domain()\\n        external\\n        view\\n        returns (\\n            bytes1 fields,\\n            string memory name,\\n            string memory version,\\n            uint256 chainId,\\n            address verifyingContract,\\n            bytes32 salt,\\n            uint256[] memory extensions\\n        );\\n}\\n\",\"keccak256\":\"0xac6c2efc64baccbde4904ae18ed45139c9aa8cff96d6888344d1e4d2eb8b659f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuard {\\n    // Booleans are more expensive than uint256 or any type that takes up a full\\n    // word because each write operation emits an extra SLOAD to first read the\\n    // slot's contents, replace the bits taken up by the boolean, and then write\\n    // back. This is the compiler's defense against contract upgrades and\\n    // pointer aliasing, and it cannot be disabled.\\n\\n    // The values being non-zero value makes deployment a bit more expensive,\\n    // but in exchange the refund on every call to nonReentrant will be lower in\\n    // amount. Since refunds are capped to a percentage of the total\\n    // transaction's gas, it is best to keep them low in cases like this one, to\\n    // increase the likelihood of the full refund coming into effect.\\n    uint256 private constant _NOT_ENTERED = 1;\\n    uint256 private constant _ENTERED = 2;\\n\\n    uint256 private _status;\\n\\n    constructor() {\\n        _status = _NOT_ENTERED;\\n    }\\n\\n    /**\\n     * @dev Prevents a contract from calling itself, directly or indirectly.\\n     * Calling a `nonReentrant` function from another `nonReentrant`\\n     * function is not supported. It is possible to prevent this from happening\\n     * by making the `nonReentrant` function external, and making it call a\\n     * `private` function that does the actual work.\\n     */\\n    modifier nonReentrant() {\\n        _nonReentrantBefore();\\n        _;\\n        _nonReentrantAfter();\\n    }\\n\\n    function _nonReentrantBefore() private {\\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\\n        require(_status != _ENTERED, \\\"ReentrancyGuard: reentrant call\\\");\\n\\n        // Any calls to nonReentrant after this point will fail\\n        _status = _ENTERED;\\n    }\\n\\n    function _nonReentrantAfter() private {\\n        // By storing the original value once again, a refund is triggered (see\\n        // https://eips.ethereum.org/EIPS/eip-2200)\\n        _status = _NOT_ENTERED;\\n    }\\n\\n    /**\\n     * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n     * `nonReentrant` function in the call stack.\\n     */\\n    function _reentrancyGuardEntered() internal view returns (bool) {\\n        return _status == _ENTERED;\\n    }\\n}\\n\",\"keccak256\":\"0xa535a5df777d44e945dd24aa43a11e44b024140fc340ad0dfe42acf4002aade1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes calldata) {\\n        return msg.data;\\n    }\\n\\n    function _contextSuffixLength() internal view virtual returns (uint256) {\\n        return 0;\\n    }\\n}\\n\",\"keccak256\":\"0xa92e4fa126feb6907daa0513ddd816b2eb91f30a808de54f63c17d0e162c3439\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/ShortStrings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol)\\n\\npragma solidity ^0.8.8;\\n\\nimport \\\"./StorageSlot.sol\\\";\\n\\n// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |\\n// | length  | 0x                                                              BB |\\ntype ShortString is bytes32;\\n\\n/**\\n * @dev This library provides functions to convert short memory strings\\n * into a `ShortString` type that can be used as an immutable variable.\\n *\\n * Strings of arbitrary length can be optimized using this library if\\n * they are short enough (up to 31 bytes) by packing them with their\\n * length (1 byte) in a single EVM word (32 bytes). Additionally, a\\n * fallback mechanism can be used for every other case.\\n *\\n * Usage example:\\n *\\n * ```solidity\\n * contract Named {\\n *     using ShortStrings for *;\\n *\\n *     ShortString private immutable _name;\\n *     string private _nameFallback;\\n *\\n *     constructor(string memory contractName) {\\n *         _name = contractName.toShortStringWithFallback(_nameFallback);\\n *     }\\n *\\n *     function name() external view returns (string memory) {\\n *         return _name.toStringWithFallback(_nameFallback);\\n *     }\\n * }\\n * ```\\n */\\nlibrary ShortStrings {\\n    // Used as an identifier for strings longer than 31 bytes.\\n    bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;\\n\\n    error StringTooLong(string str);\\n    error InvalidShortString();\\n\\n    /**\\n     * @dev Encode a string of at most 31 chars into a `ShortString`.\\n     *\\n     * This will trigger a `StringTooLong` error is the input string is too long.\\n     */\\n    function toShortString(string memory str) internal pure returns (ShortString) {\\n        bytes memory bstr = bytes(str);\\n        if (bstr.length > 31) {\\n            revert StringTooLong(str);\\n        }\\n        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));\\n    }\\n\\n    /**\\n     * @dev Decode a `ShortString` back to a \\\"normal\\\" string.\\n     */\\n    function toString(ShortString sstr) internal pure returns (string memory) {\\n        uint256 len = byteLength(sstr);\\n        // using `new string(len)` would work locally but is not memory safe.\\n        string memory str = new string(32);\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            mstore(str, len)\\n            mstore(add(str, 0x20), sstr)\\n        }\\n        return str;\\n    }\\n\\n    /**\\n     * @dev Return the length of a `ShortString`.\\n     */\\n    function byteLength(ShortString sstr) internal pure returns (uint256) {\\n        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;\\n        if (result > 31) {\\n            revert InvalidShortString();\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.\\n     */\\n    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {\\n        if (bytes(value).length < 32) {\\n            return toShortString(value);\\n        } else {\\n            StorageSlot.getStringSlot(store).value = value;\\n            return ShortString.wrap(_FALLBACK_SENTINEL);\\n        }\\n    }\\n\\n    /**\\n     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.\\n     */\\n    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {\\n        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {\\n            return toString(value);\\n        } else {\\n            return store;\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}.\\n     *\\n     * WARNING: This will return the \\\"byte length\\\" of the string. This may not reflect the actual length in terms of\\n     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.\\n     */\\n    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {\\n        if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) {\\n            return byteLength(value);\\n        } else {\\n            return bytes(store).length;\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xc0e310c163edf15db45d4ff938113ab357f94fa86e61ea8e790853c4d2e13256\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```solidity\\n * contract ERC1967 {\\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n *     function _getImplementation() internal view returns (address) {\\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n *     }\\n *\\n *     function _setImplementation(address newImplementation) internal {\\n *         require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n *     }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\\n * _Available since v4.9 for `string`, `bytes`._\\n */\\nlibrary StorageSlot {\\n    struct AddressSlot {\\n        address value;\\n    }\\n\\n    struct BooleanSlot {\\n        bool value;\\n    }\\n\\n    struct Bytes32Slot {\\n        bytes32 value;\\n    }\\n\\n    struct Uint256Slot {\\n        uint256 value;\\n    }\\n\\n    struct StringSlot {\\n        string value;\\n    }\\n\\n    struct BytesSlot {\\n        bytes value;\\n    }\\n\\n    /**\\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n     */\\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n     */\\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n     */\\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n     */\\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\\n     */\\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\\n     */\\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := store.slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\\n     */\\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := slot\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\\n     */\\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            r.slot := store.slot\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xf09e68aa0dc6722a25bc46490e8d48ed864466d17313b8a0b254c36b54e49899\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\nimport \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n    bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n    uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            uint256 length = Math.log10(value) + 1;\\n            string memory buffer = new string(length);\\n            uint256 ptr;\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                ptr := add(buffer, add(32, length))\\n            }\\n            while (true) {\\n                ptr--;\\n                /// @solidity memory-safe-assembly\\n                assembly {\\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n                }\\n                value /= 10;\\n                if (value == 0) break;\\n            }\\n            return buffer;\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n     */\\n    function toString(int256 value) internal pure returns (string memory) {\\n        return string(abi.encodePacked(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value))));\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(uint256 value) internal pure returns (string memory) {\\n        unchecked {\\n            return toHexString(value, Math.log256(value) + 1);\\n        }\\n    }\\n\\n    /**\\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n     */\\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n        bytes memory buffer = new bytes(2 * length + 2);\\n        buffer[0] = \\\"0\\\";\\n        buffer[1] = \\\"x\\\";\\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\\n            buffer[i] = _SYMBOLS[value & 0xf];\\n            value >>= 4;\\n        }\\n        require(value == 0, \\\"Strings: hex length insufficient\\\");\\n        return string(buffer);\\n    }\\n\\n    /**\\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n     */\\n    function toHexString(address addr) internal pure returns (string memory) {\\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n    }\\n\\n    /**\\n     * @dev Returns true if the two strings are equal.\\n     */\\n    function equal(string memory a, string memory b) internal pure returns (bool) {\\n        return keccak256(bytes(a)) == keccak256(bytes(b));\\n    }\\n}\\n\",\"keccak256\":\"0x3088eb2868e8d13d89d16670b5f8612c4ab9ff8956272837d8e90106c59c14a0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n    enum RecoverError {\\n        NoError,\\n        InvalidSignature,\\n        InvalidSignatureLength,\\n        InvalidSignatureS,\\n        InvalidSignatureV // Deprecated in v4.8\\n    }\\n\\n    function _throwError(RecoverError error) private pure {\\n        if (error == RecoverError.NoError) {\\n            return; // no error: do nothing\\n        } else if (error == RecoverError.InvalidSignature) {\\n            revert(\\\"ECDSA: invalid signature\\\");\\n        } else if (error == RecoverError.InvalidSignatureLength) {\\n            revert(\\\"ECDSA: invalid signature length\\\");\\n        } else if (error == RecoverError.InvalidSignatureS) {\\n            revert(\\\"ECDSA: invalid signature 's' value\\\");\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the address that signed a hashed message (`hash`) with\\n     * `signature` or error string. This address can then be used for verification purposes.\\n     *\\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n     * this function rejects them by requiring the `s` value to be in the lower\\n     * half order, and the `v` value to be either 27 or 28.\\n     *\\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n     * verification to be secure: it is possible to craft signatures that\\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n     * this is by receiving a hash of the original message (which may otherwise\\n     * be too long), and then calling {toEthSignedMessageHash} on it.\\n     *\\n     * Documentation for signature generation:\\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n        if (signature.length == 65) {\\n            bytes32 r;\\n            bytes32 s;\\n            uint8 v;\\n            // ecrecover takes the signature parameters, and the only way to get them\\n            // currently is to use assembly.\\n            /// @solidity memory-safe-assembly\\n            assembly {\\n                r := mload(add(signature, 0x20))\\n                s := mload(add(signature, 0x40))\\n                v := byte(0, mload(add(signature, 0x60)))\\n            }\\n            return tryRecover(hash, v, r, s);\\n        } else {\\n            return (address(0), RecoverError.InvalidSignatureLength);\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns the address that signed a hashed message (`hash`) with\\n     * `signature`. This address can then be used for verification purposes.\\n     *\\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n     * this function rejects them by requiring the `s` value to be in the lower\\n     * half order, and the `v` value to be either 27 or 28.\\n     *\\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n     * verification to be secure: it is possible to craft signatures that\\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n     * this is by receiving a hash of the original message (which may otherwise\\n     * be too long), and then calling {toEthSignedMessageHash} on it.\\n     */\\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n     *\\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {\\n        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n        uint8 v = uint8((uint256(vs) >> 255) + 27);\\n        return tryRecover(hash, v, r, s);\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n     *\\n     * _Available since v4.2._\\n     */\\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n     * `r` and `s` signature fields separately.\\n     *\\n     * _Available since v4.3._\\n     */\\n    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {\\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n        // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n        //\\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n        // these malleable signatures as well.\\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n            return (address(0), RecoverError.InvalidSignatureS);\\n        }\\n\\n        // If the signature is valid (and not malleable), return the signer address\\n        address signer = ecrecover(hash, v, r, s);\\n        if (signer == address(0)) {\\n            return (address(0), RecoverError.InvalidSignature);\\n        }\\n\\n        return (signer, RecoverError.NoError);\\n    }\\n\\n    /**\\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\\n     * `r` and `s` signature fields separately.\\n     */\\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n        _throwError(error);\\n        return recovered;\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n     * produces hash corresponding to the one signed with the\\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n     * JSON-RPC method as part of EIP-191.\\n     *\\n     * See {recover}.\\n     */\\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\\n        // 32 is the length in bytes of hash,\\n        // enforced by the type signature above\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\")\\n            mstore(0x1c, hash)\\n            message := keccak256(0x00, 0x3c)\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\\n     * produces hash corresponding to the one signed with the\\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n     * JSON-RPC method as part of EIP-191.\\n     *\\n     * See {recover}.\\n     */\\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Typed Data, created from a\\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\\n     * to the one signed with the\\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n     * JSON-RPC method as part of EIP-712.\\n     *\\n     * See {recover}.\\n     */\\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\\n        /// @solidity memory-safe-assembly\\n        assembly {\\n            let ptr := mload(0x40)\\n            mstore(ptr, \\\"\\\\x19\\\\x01\\\")\\n            mstore(add(ptr, 0x02), domainSeparator)\\n            mstore(add(ptr, 0x22), structHash)\\n            data := keccak256(ptr, 0x42)\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\\n     * `validator` and `data` according to the version 0 of EIP-191.\\n     *\\n     * See {recover}.\\n     */\\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n        return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x00\\\", validator, data));\\n    }\\n}\\n\",\"keccak256\":\"0x809bc3edb4bcbef8263fa616c1b60ee0004b50a8a1bfa164d8f57fd31f520c58\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.8;\\n\\nimport \\\"./ECDSA.sol\\\";\\nimport \\\"../ShortStrings.sol\\\";\\nimport \\\"../../interfaces/IERC5267.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 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n */\\nabstract contract EIP712 is IERC5267 {\\n    using ShortStrings for *;\\n\\n    bytes32 private constant _TYPE_HASH =\\n        keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\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 _cachedDomainSeparator;\\n    uint256 private immutable _cachedChainId;\\n    address private immutable _cachedThis;\\n\\n    bytes32 private immutable _hashedName;\\n    bytes32 private immutable _hashedVersion;\\n\\n    ShortString private immutable _name;\\n    ShortString private immutable _version;\\n    string private _nameFallback;\\n    string private _versionFallback;\\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        _name = name.toShortStringWithFallback(_nameFallback);\\n        _version = version.toShortStringWithFallback(_versionFallback);\\n        _hashedName = keccak256(bytes(name));\\n        _hashedVersion = keccak256(bytes(version));\\n\\n        _cachedChainId = block.chainid;\\n        _cachedDomainSeparator = _buildDomainSeparator();\\n        _cachedThis = address(this);\\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) == _cachedThis && block.chainid == _cachedChainId) {\\n            return _cachedDomainSeparator;\\n        } else {\\n            return _buildDomainSeparator();\\n        }\\n    }\\n\\n    function _buildDomainSeparator() private view returns (bytes32) {\\n        return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, 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    /**\\n     * @dev See {EIP-5267}.\\n     *\\n     * _Available since v4.9._\\n     */\\n    function eip712Domain()\\n        public\\n        view\\n        virtual\\n        override\\n        returns (\\n            bytes1 fields,\\n            string memory name,\\n            string memory version,\\n            uint256 chainId,\\n            address verifyingContract,\\n            bytes32 salt,\\n            uint256[] memory extensions\\n        )\\n    {\\n        return (\\n            hex\\\"0f\\\", // 01111\\n            _name.toStringWithFallback(_nameFallback),\\n            _version.toStringWithFallback(_versionFallback),\\n            block.chainid,\\n            address(this),\\n            bytes32(0),\\n            new uint256[](0)\\n        );\\n    }\\n}\\n\",\"keccak256\":\"0x8432884527a7ad91e6eed1cfc5a0811ae2073e5bca107bd0ca442e9236b03dbd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n    enum Rounding {\\n        Down, // Toward negative infinity\\n        Up, // Toward infinity\\n        Zero // Toward zero\\n    }\\n\\n    /**\\n     * @dev Returns the largest of two numbers.\\n     */\\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two numbers.\\n     */\\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two numbers. The result is rounded towards\\n     * zero.\\n     */\\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b) / 2 can overflow.\\n        return (a & b) + (a ^ b) / 2;\\n    }\\n\\n    /**\\n     * @dev Returns the ceiling of the division of two numbers.\\n     *\\n     * This differs from standard division with `/` in that it rounds up instead\\n     * of rounding down.\\n     */\\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // (a + b - 1) / b can overflow on addition, so we distribute.\\n        return a == 0 ? 0 : (a - 1) / b + 1;\\n    }\\n\\n    /**\\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n     * with further edits by Uniswap Labs also under MIT license.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n        unchecked {\\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n            // variables such that product = prod1 * 2^256 + prod0.\\n            uint256 prod0; // Least significant 256 bits of the product\\n            uint256 prod1; // Most significant 256 bits of the product\\n            assembly {\\n                let mm := mulmod(x, y, not(0))\\n                prod0 := mul(x, y)\\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n            }\\n\\n            // Handle non-overflow cases, 256 by 256 division.\\n            if (prod1 == 0) {\\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n                // The surrounding unchecked block does not change this fact.\\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n                return prod0 / denominator;\\n            }\\n\\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n            require(denominator > prod1, \\\"Math: mulDiv overflow\\\");\\n\\n            ///////////////////////////////////////////////\\n            // 512 by 256 division.\\n            ///////////////////////////////////////////////\\n\\n            // Make division exact by subtracting the remainder from [prod1 prod0].\\n            uint256 remainder;\\n            assembly {\\n                // Compute remainder using mulmod.\\n                remainder := mulmod(x, y, denominator)\\n\\n                // Subtract 256 bit number from 512 bit number.\\n                prod1 := sub(prod1, gt(remainder, prod0))\\n                prod0 := sub(prod0, remainder)\\n            }\\n\\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n            // See https://cs.stackexchange.com/q/138556/92363.\\n\\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\\n            uint256 twos = denominator & (~denominator + 1);\\n            assembly {\\n                // Divide denominator by twos.\\n                denominator := div(denominator, twos)\\n\\n                // Divide [prod1 prod0] by twos.\\n                prod0 := div(prod0, twos)\\n\\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n                twos := add(div(sub(0, twos), twos), 1)\\n            }\\n\\n            // Shift in bits from prod1 into prod0.\\n            prod0 |= prod1 * twos;\\n\\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n            // four bits. That is, denominator * inv = 1 mod 2^4.\\n            uint256 inverse = (3 * denominator) ^ 2;\\n\\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n            // in modular arithmetic, doubling the correct bits in each step.\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n            // is no longer required.\\n            result = prod0 * inverse;\\n            return result;\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n     */\\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n        uint256 result = mulDiv(x, y, denominator);\\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n            result += 1;\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n     *\\n     * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n     */\\n    function sqrt(uint256 a) internal pure returns (uint256) {\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n        //\\n        // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n        //\\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n        // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n        // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n        //\\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n        uint256 result = 1 << (log2(a) >> 1);\\n\\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n        // into the expected uint128 result.\\n        unchecked {\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            result = (result + a / result) >> 1;\\n            return min(result, a / result);\\n        }\\n    }\\n\\n    /**\\n     * @notice Calculates sqrt(a), following the selected rounding direction.\\n     */\\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = sqrt(a);\\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 128;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 64;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 32;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 16;\\n            }\\n            if (value >> 8 > 0) {\\n                value >>= 8;\\n                result += 8;\\n            }\\n            if (value >> 4 > 0) {\\n                value >>= 4;\\n                result += 4;\\n            }\\n            if (value >> 2 > 0) {\\n                value >>= 2;\\n                result += 2;\\n            }\\n            if (value >> 1 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log2(value);\\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >= 10 ** 64) {\\n                value /= 10 ** 64;\\n                result += 64;\\n            }\\n            if (value >= 10 ** 32) {\\n                value /= 10 ** 32;\\n                result += 32;\\n            }\\n            if (value >= 10 ** 16) {\\n                value /= 10 ** 16;\\n                result += 16;\\n            }\\n            if (value >= 10 ** 8) {\\n                value /= 10 ** 8;\\n                result += 8;\\n            }\\n            if (value >= 10 ** 4) {\\n                value /= 10 ** 4;\\n                result += 4;\\n            }\\n            if (value >= 10 ** 2) {\\n                value /= 10 ** 2;\\n                result += 2;\\n            }\\n            if (value >= 10 ** 1) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log10(value);\\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\\n        }\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, rounded down, of a positive value.\\n     * Returns 0 if given 0.\\n     *\\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n     */\\n    function log256(uint256 value) internal pure returns (uint256) {\\n        uint256 result = 0;\\n        unchecked {\\n            if (value >> 128 > 0) {\\n                value >>= 128;\\n                result += 16;\\n            }\\n            if (value >> 64 > 0) {\\n                value >>= 64;\\n                result += 8;\\n            }\\n            if (value >> 32 > 0) {\\n                value >>= 32;\\n                result += 4;\\n            }\\n            if (value >> 16 > 0) {\\n                value >>= 16;\\n                result += 2;\\n            }\\n            if (value >> 8 > 0) {\\n                result += 1;\\n            }\\n        }\\n        return result;\\n    }\\n\\n    /**\\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n     * Returns 0 if given 0.\\n     */\\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n        unchecked {\\n            uint256 result = log256(value);\\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xe4455ac1eb7fc497bb7402579e7b4d64d928b846fce7d2b6fde06d366f21c2b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n    /**\\n     * @dev Returns the largest of two signed numbers.\\n     */\\n    function max(int256 a, int256 b) internal pure returns (int256) {\\n        return a > b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the smallest of two signed numbers.\\n     */\\n    function min(int256 a, int256 b) internal pure returns (int256) {\\n        return a < b ? a : b;\\n    }\\n\\n    /**\\n     * @dev Returns the average of two signed numbers without overflow.\\n     * The result is rounded towards zero.\\n     */\\n    function average(int256 a, int256 b) internal pure returns (int256) {\\n        // Formula from the book \\\"Hacker's Delight\\\"\\n        int256 x = (a & b) + ((a ^ b) >> 1);\\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\\n    }\\n\\n    /**\\n     * @dev Returns the absolute unsigned value of a signed value.\\n     */\\n    function abs(int256 n) internal pure returns (uint256) {\\n        unchecked {\\n            // must be unchecked in order to support `n = type(int256).min`\\n            return uint256(n >= 0 ? n : -n);\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xf92515413956f529d95977adc9b0567d583c6203fc31ab1c23824c35187e3ddc\",\"license\":\"MIT\"},\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n    function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n    function updatePrice(address vToken) external;\\n\\n    function updateAssetPrice(address asset) external;\\n\\n    function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n    function validatePriceWithAnchorPrice(\\n        address asset,\\n        uint256 reporterPrice,\\n        uint256 anchorPrice\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xd3bbb7c9eef19e8f467342df6034ef95399a00964646fb8c82b438968ae3a8c0\",\"license\":\"BSD-3-Clause\"},\"contracts/Interfaces.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\nimport { IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\nimport { ResilientOracleInterface } from \\\"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\\\";\\n\\ninterface IVToken is IERC20Upgradeable {\\n    function accrueInterest() external returns (uint256);\\n\\n    function redeem(uint256 redeemTokens) external returns (uint256);\\n\\n    function redeemUnderlying(uint256 redeemAmount) external returns (uint256);\\n\\n    function borrowBalanceCurrent(address borrower) external returns (uint256);\\n\\n    function balanceOfUnderlying(address owner) external returns (uint256);\\n\\n    function seize(address liquidator, address borrower, uint seizeTokens) external returns (uint);\\n\\n    function mintBehalf(address receiver, uint mintAmount) external returns (uint);\\n\\n    function borrowBehalf(address borrower, uint borrowAmount) external returns (uint256);\\n\\n    function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint256);\\n\\n    function comptroller() external view returns (IComptroller);\\n\\n    function borrowBalanceStored(address account) external view returns (uint256);\\n\\n    function underlying() external view returns (address);\\n}\\n\\ninterface IVBNB is IVToken {\\n    function repayBorrowBehalf(address borrower) external payable;\\n\\n    function liquidateBorrow(address borrower, IVToken vTokenCollateral) external payable;\\n}\\n\\ninterface IComptroller {\\n    enum Action {\\n        MINT,\\n        REDEEM,\\n        BORROW,\\n        REPAY,\\n        SEIZE,\\n        LIQUIDATE,\\n        TRANSFER,\\n        ENTER_MARKET,\\n        EXIT_MARKET\\n    }\\n\\n    function _setActionsPaused(address[] calldata markets_, Action[] calldata actions_, bool paused_) external;\\n\\n    function enterMarkets(address[] calldata vTokens) external returns (uint256[] memory);\\n\\n    function enterMarket(address user, address vToken) external returns (uint256);\\n\\n    function liquidationIncentiveMantissa() external view returns (uint256);\\n\\n    function vaiController() external view returns (address);\\n\\n    function liquidatorContract() external view returns (address);\\n\\n    function oracle() external view returns (ResilientOracleInterface);\\n\\n    function actionPaused(address market, Action action) external view returns (bool);\\n\\n    function markets(address) external view returns (bool, uint256, bool);\\n\\n    function isForcedLiquidationEnabled(address) external view returns (bool);\\n\\n    function approvedDelegates(address borrower, address delegate) external view returns (bool);\\n\\n    function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);\\n\\n    function checkMembership(address account, IVToken vToken) external view returns (bool);\\n}\\n\\ninterface IWBNB is IERC20Upgradeable {\\n    function deposit() external payable;\\n\\n    function withdraw(uint256 amount) external;\\n}\\n\",\"keccak256\":\"0x5e3f7e439dcb7a2be85757b488fd420c177c7d9b3b5edcd9e630b68bbcc75303\",\"license\":\"BSD-3-Clause\"},\"contracts/SwapHelper/SwapHelper.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.28;\\n\\nimport { SafeERC20Upgradeable, IERC20Upgradeable } from \\\"@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol\\\";\\nimport { AddressUpgradeable } from \\\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\\\";\\nimport { EIP712 } from \\\"@openzeppelin/contracts/utils/cryptography/EIP712.sol\\\";\\nimport { ECDSA } from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ReentrancyGuard } from \\\"@openzeppelin/contracts/security/ReentrancyGuard.sol\\\";\\n\\nimport { IWBNB } from \\\"../Interfaces.sol\\\";\\n\\n/**\\n * @title SwapHelper\\n * @author Venus Protocol\\n * @notice Helper contract for executing multiple token operations atomically\\n * @dev This contract provides utilities for wrapping native tokens, managing approvals,\\n *      and executing arbitrary calls in a single transaction. It supports optional\\n *      signature verification using EIP-712 for backend-authorized operations.\\n *      All functions except multicall are designed to be called internally via multicall.\\n * @custom:security-contact security@venus.io\\n */\\ncontract SwapHelper is EIP712, Ownable, ReentrancyGuard {\\n    using SafeERC20Upgradeable for IERC20Upgradeable;\\n    using AddressUpgradeable for address;\\n\\n    /// @notice EIP-712 typehash for Multicall struct used in signature verification\\n    /// @dev keccak256(\\\"Multicall(bytes[] calls,uint256 deadline,bytes32 salt)\\\")\\n    bytes32 internal constant MULTICALL_TYPEHASH = keccak256(\\\"Multicall(bytes[] calls,uint256 deadline,bytes32 salt)\\\");\\n\\n    /// @notice Wrapped native asset contract (e.g., WBNB, WETH)\\n    IWBNB public immutable WRAPPED_NATIVE;\\n\\n    /// @notice Address authorized to sign multicall operations\\n    /// @dev Can be updated by contract owner via setBackendSigner\\n    address public backendSigner;\\n\\n    /// @notice Mapping to track used salts for replay protection\\n    /// @dev Maps salt => bool to prevent reuse of same salt\\n    mapping(bytes32 => bool) public usedSalts;\\n\\n    /// @notice Error thrown when transaction deadline has passed\\n    /// @dev Emitted when block.timestamp > deadline in multicall\\n    error DeadlineReached();\\n\\n    /// @notice Error thrown when signature verification fails\\n    /// @dev Emitted when recovered signer doesn't match backendSigner\\n    error Unauthorized();\\n\\n    /// @notice Error thrown when zero address is provided as parameter\\n    /// @dev Used in constructor and setBackendSigner validation\\n    error ZeroAddress();\\n\\n    /// @notice Error thrown when salt has already been used\\n    /// @dev Prevents replay attacks by ensuring each salt is used only once\\n    error SaltAlreadyUsed();\\n\\n    /// @notice Error thrown when caller is not authorized\\n    /// @dev Only owner or contract itself can call protected functions\\n    error CallerNotAuthorized();\\n\\n    /// @notice Error thrown when no calls are provided to multicall\\n    /// @dev Emitted when calls array is empty in multicall\\n    error NoCallsProvided();\\n\\n    /// @notice Error thrown when signature is missing but required\\n    /// @dev Emitted when signature length is zero but verification is expected\\n    error MissingSignature();\\n\\n    /// @notice Event emitted when backend signer is updated\\n    /// @param oldSigner Previous backend signer address\\n    /// @param newSigner New backend signer address\\n    event BackendSignerUpdated(address indexed oldSigner, address indexed newSigner);\\n\\n    /// @notice Event emitted when multicall is successfully executed\\n    /// @param caller Address that initiated the multicall\\n    /// @param callsCount Number of calls executed in the batch\\n    /// @param deadline Deadline timestamp used for the operation\\n    /// @param salt Salt used for replay protection\\n    event MulticallExecuted(address indexed caller, uint256 callsCount, uint256 deadline, bytes32 salt);\\n\\n    /// @notice Constructor\\n    /// @param wrappedNative_ Address of the wrapped native asset contract\\n    /// @param backendSigner_ Address authorized to sign multicall operations\\n    /// @dev Initializes EIP-712 domain with name \\\"VenusSwap\\\" and version \\\"1\\\"\\n    /// @dev Transfers ownership to msg.sender\\n    /// @dev Reverts with ZeroAddress if either parameter is address(0)\\n    /// @custom:error ZeroAddress if wrappedNative_ is address(0)\\n    /// @custom:error ZeroAddress if backendSigner_ is address(0)\\n    constructor(address wrappedNative_, address backendSigner_) EIP712(\\\"VenusSwap\\\", \\\"1\\\") {\\n        if (wrappedNative_ == address(0) || backendSigner_ == address(0)) {\\n            revert ZeroAddress();\\n        }\\n\\n        WRAPPED_NATIVE = IWBNB(wrappedNative_);\\n        backendSigner = backendSigner_;\\n    }\\n\\n    /// @notice Modifier to restrict access to owner or contract itself\\n    /// @dev Reverts with CallerNotAuthorized if caller is neither owner nor this contract\\n    modifier onlyOwnerOrSelf() {\\n        if (msg.sender != owner() && msg.sender != address(this)) {\\n            revert CallerNotAuthorized();\\n        }\\n        _;\\n    }\\n\\n    /// @notice Multicall function to execute multiple calls in a single transaction\\n    /// @param calls Array of encoded function calls to execute on this contract\\n    /// @param deadline Unix timestamp after which the transaction will revert\\n    /// @param salt Unique value to ensure this exact multicall can only be executed once\\n    /// @param signature Optional EIP-712 signature from backend signer (empty bytes to skip verification)\\n    /// @dev All calls are executed atomically - if any call fails, entire transaction reverts\\n    /// @dev Calls must be to functions on this contract (address(this))\\n    /// @dev Signature verification is only performed if signature.length != 0\\n    /// @dev Protected by nonReentrant modifier to prevent reentrancy attacks\\n    /// @dev Emits MulticallExecuted event upon successful execution\\n    /// @custom:security Only the contract itself can call wrap, sweep, approveMax, and genericCall\\n    /// @custom:error NoCallsProvided if calls array is empty\\n    /// @custom:error DeadlineReached if block.timestamp > deadline\\n    /// @custom:error SaltAlreadyUsed if salt has been used before\\n    /// @custom:error Unauthorized if signature verification fails\\n    function multicall(\\n        bytes[] calldata calls,\\n        uint256 deadline,\\n        bytes32 salt,\\n        bytes calldata signature\\n    ) external payable nonReentrant {\\n        if (calls.length == 0) {\\n            revert NoCallsProvided();\\n        }\\n\\n        if (block.timestamp > deadline) {\\n            revert DeadlineReached();\\n        }\\n\\n        if (signature.length == 0) {\\n            revert MissingSignature();\\n        }\\n        if (usedSalts[salt]) {\\n            revert SaltAlreadyUsed();\\n        }\\n        usedSalts[salt] = true;\\n\\n        bytes32 digest = _hashMulticall(calls, deadline, salt);\\n        address signer = ECDSA.recover(digest, signature);\\n        if (signer != backendSigner) {\\n            revert Unauthorized();\\n        }\\n\\n        for (uint256 i = 0; i < calls.length; i++) {\\n            (bool success, bytes memory returnData) = address(this).call(calls[i]);\\n            if (!success) {\\n                assembly {\\n                    revert(add(returnData, 0x20), mload(returnData))\\n                }\\n            }\\n        }\\n\\n        emit MulticallExecuted(msg.sender, calls.length, deadline, salt);\\n    }\\n\\n    /// @notice Generic call function to execute a call to an arbitrary address\\n    /// @param target Address of the contract to call\\n    /// @param data Encoded function call data\\n    /// @dev This function can interact with any external contract\\n    /// @dev Should only be called via multicall for safety\\n    /// @custom:security Use with extreme caution - can call any contract with any data\\n    /// @custom:security Ensure proper validation of target and data in off-chain systems\\n    /// @custom:error CallerNotAuthorized if caller is not owner or contract itself\\n    function genericCall(address target, bytes calldata data) external payable onlyOwnerOrSelf {\\n        target.functionCall(data);\\n    }\\n\\n    /// @notice Wraps native asset into an ERC-20 wrapped token\\n    /// @param amount Amount of native asset to wrap (must match msg.value)\\n    /// @dev Calls deposit() on WRAPPED_NATIVE contract with msg.value\\n    /// @dev Wrapped tokens remain in this contract until swept\\n    /// @dev Should only be called via multicall\\n    /// @custom:security Ensure msg.value matches amount parameter\\n    /// @custom:error CallerNotAuthorized if caller is not owner or contract itself\\n    function wrap(uint256 amount) external payable onlyOwnerOrSelf {\\n        WRAPPED_NATIVE.deposit{ value: amount }();\\n    }\\n\\n    /// @notice Sweeps entire balance of an ERC-20 token to a specified address\\n    /// @param token ERC-20 token contract to sweep\\n    /// @param to Recipient address for the swept tokens\\n    /// @dev Transfers the entire balance of token held by this contract\\n    /// @dev Uses SafeERC20 for safe transfer operations\\n    /// @dev Should only be called via multicall\\n    /// @custom:error CallerNotAuthorized if caller is not owner or contract itself\\n    function sweep(IERC20Upgradeable token, address to) external onlyOwnerOrSelf {\\n        token.safeTransfer(to, token.balanceOf(address(this)));\\n    }\\n\\n    /// @notice Approves maximum amount of an ERC-20 token to a specified spender\\n    /// @param token ERC-20 token contract to approve\\n    /// @param spender Address to grant approval to\\n    /// @dev Sets approval to type(uint256).max for unlimited spending\\n    /// @dev Uses forceApprove to handle tokens that require 0 approval first\\n    /// @dev Should only be called via multicall\\n    /// @custom:security Grants unlimited approval - ensure spender is trusted\\n    /// @custom:error CallerNotAuthorized if caller is not owner or contract itself\\n    function approveMax(IERC20Upgradeable token, address spender) external onlyOwnerOrSelf {\\n        token.forceApprove(spender, type(uint256).max);\\n    }\\n\\n    /// @notice Updates the backend signer address\\n    /// @param newSigner New backend signer address\\n    /// @dev Only callable by contract owner\\n    /// @dev Reverts with ZeroAddress if newSigner is address(0)\\n    /// @dev Emits BackendSignerUpdated event\\n    /// @custom:error ZeroAddress if newSigner is address(0)\\n    /// @custom:error Ownable: caller is not the owner (from OpenZeppelin Ownable)\\n    function setBackendSigner(address newSigner) external onlyOwner {\\n        if (newSigner == address(0)) {\\n            revert ZeroAddress();\\n        }\\n        address oldSigner = backendSigner;\\n        backendSigner = newSigner;\\n\\n        emit BackendSignerUpdated(oldSigner, newSigner);\\n    }\\n\\n    /// @notice Produces an EIP-712 digest of the multicall data\\n    /// @param calls Array of encoded function calls\\n    /// @param deadline Unix timestamp deadline\\n    /// @param salt Unique value to ensure replay protection\\n    /// @return EIP-712 typed data hash for signature verification\\n    /// @dev Hashes each call individually, then encodes with MULTICALL_TYPEHASH, deadline, and salt\\n    /// @dev Uses EIP-712 _hashTypedDataV4 for domain-separated hashing\\n    function _hashMulticall(bytes[] calldata calls, uint256 deadline, bytes32 salt) internal view returns (bytes32) {\\n        bytes32[] memory callHashes = new bytes32[](calls.length);\\n        for (uint256 i = 0; i < calls.length; i++) {\\n            callHashes[i] = keccak256(calls[i]);\\n        }\\n        return\\n            _hashTypedDataV4(\\n                keccak256(abi.encode(MULTICALL_TYPEHASH, keccak256(abi.encodePacked(callHashes)), deadline, salt))\\n            );\\n    }\\n}\\n\",\"keccak256\":\"0x7a82fc0491ba979d9b0f7519d4e971ec5553d142d41e1ed89e1ad974bac49bb2\",\"license\":\"BSD-3-Clause\"}},\"version\":1}",
  "bytecode": "0x610180604052348015610010575f5ffd5b50604051611c80380380611c8083398101604081905261002f9161026c565b6040805180820182526009815268056656e7573537761760bc1b602080830191909152825180840190935260018352603160f81b9083015290610072825f610188565b61012052610081816001610188565b61014052815160208084019190912060e052815190820120610100524660a05261010d60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b60805250503060c05261011f336101ba565b60016003556001600160a01b038216158061014157506001600160a01b038116155b1561015f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0391821661016052600480546001600160a01b03191691909216179055610447565b5f6020835110156101a35761019c8361020b565b90506101b4565b816101ae8482610335565b5060ff90505b92915050565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f5f829050601f8151111561023e578260405163305a27a960e01b815260040161023591906103ef565b60405180910390fd5b805161024982610424565b179392505050565b80516001600160a01b0381168114610267575f5ffd5b919050565b5f5f6040838503121561027d575f5ffd5b61028683610251565b915061029460208401610251565b90509250929050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806102c557607f821691505b6020821081036102e357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561033057805f5260205f20601f840160051c8101602085101561030e5750805b601f840160051c820191505b8181101561032d575f815560010161031a565b50505b505050565b81516001600160401b0381111561034e5761034e61029d565b6103628161035c84546102b1565b846102e9565b6020601f821160018114610394575f831561037d5750848201515b5f19600385901b1c1916600184901b17845561032d565b5f84815260208120601f198516915b828110156103c357878501518255602094850194600190920191016103a3565b50848210156103e057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b805160208083015191908110156102e3575f1960209190910360031b1b16919050565b60805160a05160c05160e051610100516101205161014051610160516117d76104a95f395f818161022b015261078401525f6103d101525f6103a701525f61127601525f61124e01525f6111a901525f6111d301525f6111fd01526117d75ff3fe6080604052600436106100bf575f3560e01c80638da5cb5b1161007c578063b8dc491b11610057578063b8dc491b146101fb578063d999984d1461021a578063ea598cb01461024d578063f2fde38b14610260575f5ffd5b80638da5cb5b146101ac578063a0e06909146101c9578063aec42a17146101dc575f5ffd5b80630b0fdb3d146100c357806336f95670146101065780634650c3081461012757806365d65e861461013a578063715018a61461017157806384b0196e14610185575b5f5ffd5b3480156100ce575f5ffd5b506100f16100dd3660046113c0565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b348015610111575f5ffd5b506101256101203660046113eb565b61027f565b005b61012561013536600461144b565b6102ff565b348015610145575f5ffd5b50600454610159906001600160a01b031681565b6040516001600160a01b0390911681526020016100fd565b34801561017c575f5ffd5b50610125610387565b348015610190575f5ffd5b5061019961039a565b6040516100fd97969594939291906114ca565b3480156101b7575f5ffd5b506002546001600160a01b0316610159565b6101256101d7366004611560565b610420565b3480156101e7575f5ffd5b506101256101f6366004611611565b610641565b348015610206575f5ffd5b50610125610215366004611611565b610693565b348015610225575f5ffd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b61012561025b3660046113c0565b610749565b34801561026b575f5ffd5b5061012561027a3660046113eb565b6107ed565b61028761086b565b6001600160a01b0381166102ae5760405163d92e233d60e01b815260040160405180910390fd5b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f93f9d0472cb0fc12887bf8f1f15cc7a197a5acd122ab23b8dcc25de0191e0d5e905f90a35050565b6002546001600160a01b0316331480159061031a5750333014155b156103385760405163c183bcef60e01b815260040160405180910390fd5b61038182828080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038716929150506108c5565b50505050565b61038f61086b565b6103985f610911565b565b5f606080828080836103cc7f000000000000000000000000000000000000000000000000000000000000000083610962565b6103f77f00000000000000000000000000000000000000000000000000000000000000006001610962565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610428610a0b565b5f85900361044957604051633ce6169160e11b815260040160405180910390fd5b8342111561046a5760405163b08ce5b360e01b815260040160405180910390fd5b5f81900361048b5760405163166c700d60e21b815260040160405180910390fd5b5f8381526005602052604090205460ff16156104ba57604051630ced304360e01b815260040160405180910390fd5b5f838152600560205260408120805460ff191660011790556104de87878787610a64565b90505f6105208285858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610ba792505050565b6004549091506001600160a01b03808316911614610550576040516282b42960e81b815260040160405180910390fd5b5f5b878110156105e9575f80308b8b8581811061056f5761056f61165c565b90506020028101906105819190611670565b60405161058f9291906116b3565b5f604051808303815f865af19150503d805f81146105c8576040519150601f19603f3d011682016040523d82523d5f602084013e6105cd565b606091505b5091509150816105df57805160208201fd5b5050600101610552565b50604080518881526020810188905290810186905233907f704d392ae0677a1e26b4358b06346bfa8e93d60615e56c3764c867b35c1474639060600160405180910390a250506106396001600355565b505050505050565b6002546001600160a01b0316331480159061065c5750333014155b1561067a5760405163c183bcef60e01b815260040160405180910390fd5b61068f6001600160a01b038316825f19610bc9565b5050565b6002546001600160a01b031633148015906106ae5750333014155b156106cc5760405163c183bcef60e01b815260040160405180910390fd5b6040516370a0823160e01b815230600482015261068f9082906001600160a01b038516906370a0823190602401602060405180830381865afa158015610714573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073891906116c2565b6001600160a01b0385169190610c8a565b6002546001600160a01b031633148015906107645750333014155b156107825760405163c183bcef60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b1580156107db575f5ffd5b505af1158015610639573d5f5f3e3d5ffd5b6107f561086b565b6001600160a01b03811661085f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61086881610911565b50565b6002546001600160a01b031633146103985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610856565b606061090883835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610cbf565b90505b92915050565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b606060ff831461097c5761097583610d96565b905061090b565b818054610988906116d9565b80601f01602080910402602001604051908101604052809291908181526020018280546109b4906116d9565b80156109ff5780601f106109d6576101008083540402835291602001916109ff565b820191905f5260205f20905b8154815290600101906020018083116109e257829003601f168201915b5050505050905061090b565b600260035403610a5d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610856565b6002600355565b5f808467ffffffffffffffff811115610a7f57610a7f611648565b604051908082528060200260200182016040528015610aa8578160200160208202803683370190505b5090505f5b85811015610b1457868682818110610ac757610ac761165c565b9050602002810190610ad99190611670565b604051610ae79291906116b3565b6040518091039020828281518110610b0157610b0161165c565b6020908102919091010152600101610aad565b50610b9b7fc63ad3fbe0bcd97d53b1a1a90c2d1496c83b7094a6e25814c7e0a8205a2e1c9682604051602001610b4a9190611711565b60408051601f19818403018152828252805160209182012090830193909352810191909152606081018690526080810185905260a00160405160208183030381529060405280519060200120610dd3565b9150505b949350505050565b5f5f5f610bb48585610dff565b91509150610bc181610e41565b509392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c1a8482610f8a565b610381576040516001600160a01b03841660248201525f6044820152610c8090859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261102b565b610381848261102b565b6040516001600160a01b038316602482015260448101829052610cba90849063a9059cbb60e01b90606401610c49565b505050565b606082471015610d205760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610856565b5f5f866001600160a01b03168587604051610d3b9190611746565b5f6040518083038185875af1925050503d805f8114610d75576040519150601f19603f3d011682016040523d82523d5f602084013e610d7a565b606091505b5091509150610d8b878383876110fe565b979650505050505050565b60605f610da283611176565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f61090b610ddf61119d565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f8251604103610e33576020830151604084015160608501515f1a610e27878285856112cb565b94509450505050610e3a565b505f905060025b9250929050565b5f816004811115610e5457610e5461175c565b03610e5c5750565b6001816004811115610e7057610e7061175c565b03610ebd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610856565b6002816004811115610ed157610ed161175c565b03610f1e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610856565b6003816004811115610f3257610f3261175c565b036108685760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610856565b5f5f5f846001600160a01b031684604051610fa59190611746565b5f604051808303815f865af19150503d805f8114610fde576040519150601f19603f3d011682016040523d82523d5f602084013e610fe3565b606091505b509150915081801561100d57508051158061100d57508080602001905181019061100d9190611770565b801561102257506001600160a01b0385163b15155b95945050505050565b5f61107f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113889092919063ffffffff16565b905080515f148061109f57508080602001905181019061109f9190611770565b610cba5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610856565b6060831561116c5782515f03611165576001600160a01b0385163b6111655760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610856565b5081610b9f565b610b9f8383611396565b5f60ff8216601f81111561090b57604051632cd44ac360e21b815260040160405180910390fd5b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156111f557507f000000000000000000000000000000000000000000000000000000000000000046145b1561121f57507f000000000000000000000000000000000000000000000000000000000000000090565b6112c6604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561130057505f9050600361137f565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611351573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116611379575f6001925092505061137f565b91505f90505b94509492505050565b6060610b9f84845f85610cbf565b8151156113a65781518083602001fd5b8060405162461bcd60e51b8152600401610856919061178f565b5f602082840312156113d0575f5ffd5b5035919050565b6001600160a01b0381168114610868575f5ffd5b5f602082840312156113fb575f5ffd5b8135611406816113d7565b9392505050565b5f5f83601f84011261141d575f5ffd5b50813567ffffffffffffffff811115611434575f5ffd5b602083019150836020828501011115610e3a575f5ffd5b5f5f5f6040848603121561145d575f5ffd5b8335611468816113d7565b9250602084013567ffffffffffffffff811115611483575f5ffd5b61148f8682870161140d565b9497909650939450505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e060208201525f6114e860e083018961149c565b82810360408401526114fa818961149c565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b8181101561154f578351835260209384019390920191600101611531565b50909b9a5050505050505050505050565b5f5f5f5f5f5f60808789031215611575575f5ffd5b863567ffffffffffffffff81111561158b575f5ffd5b8701601f8101891361159b575f5ffd5b803567ffffffffffffffff8111156115b1575f5ffd5b8960208260051b84010111156115c5575f5ffd5b602091820197509550870135935060408701359250606087013567ffffffffffffffff8111156115f3575f5ffd5b6115ff89828a0161140d565b979a9699509497509295939492505050565b5f5f60408385031215611622575f5ffd5b823561162d816113d7565b9150602083013561163d816113d7565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112611685575f5ffd5b83018035915067ffffffffffffffff82111561169f575f5ffd5b602001915036819003821315610e3a575f5ffd5b818382375f9101908152919050565b5f602082840312156116d2575f5ffd5b5051919050565b600181811c908216806116ed57607f821691505b60208210810361170b57634e487b7160e01b5f52602260045260245ffd5b50919050565b81515f90829060208501835b8281101561173b57815184526020938401939091019060010161171d565b509195945050505050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215611780575f5ffd5b81518015158114611406575f5ffd5b602081525f610908602083018461149c56fea26469706673582212208ed3d70fc887cfe798b30f662a510ba930e9ad24302c1855d3f33642031380a364736f6c634300081c0033",
  "deployedBytecode": "0x6080604052600436106100bf575f3560e01c80638da5cb5b1161007c578063b8dc491b11610057578063b8dc491b146101fb578063d999984d1461021a578063ea598cb01461024d578063f2fde38b14610260575f5ffd5b80638da5cb5b146101ac578063a0e06909146101c9578063aec42a17146101dc575f5ffd5b80630b0fdb3d146100c357806336f95670146101065780634650c3081461012757806365d65e861461013a578063715018a61461017157806384b0196e14610185575b5f5ffd5b3480156100ce575f5ffd5b506100f16100dd3660046113c0565b60056020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b348015610111575f5ffd5b506101256101203660046113eb565b61027f565b005b61012561013536600461144b565b6102ff565b348015610145575f5ffd5b50600454610159906001600160a01b031681565b6040516001600160a01b0390911681526020016100fd565b34801561017c575f5ffd5b50610125610387565b348015610190575f5ffd5b5061019961039a565b6040516100fd97969594939291906114ca565b3480156101b7575f5ffd5b506002546001600160a01b0316610159565b6101256101d7366004611560565b610420565b3480156101e7575f5ffd5b506101256101f6366004611611565b610641565b348015610206575f5ffd5b50610125610215366004611611565b610693565b348015610225575f5ffd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b61012561025b3660046113c0565b610749565b34801561026b575f5ffd5b5061012561027a3660046113eb565b6107ed565b61028761086b565b6001600160a01b0381166102ae5760405163d92e233d60e01b815260040160405180910390fd5b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f93f9d0472cb0fc12887bf8f1f15cc7a197a5acd122ab23b8dcc25de0191e0d5e905f90a35050565b6002546001600160a01b0316331480159061031a5750333014155b156103385760405163c183bcef60e01b815260040160405180910390fd5b61038182828080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250506001600160a01b038716929150506108c5565b50505050565b61038f61086b565b6103985f610911565b565b5f606080828080836103cc7f000000000000000000000000000000000000000000000000000000000000000083610962565b6103f77f00000000000000000000000000000000000000000000000000000000000000006001610962565b604080515f80825260208201909252600f60f81b9b939a50919850469750309650945092509050565b610428610a0b565b5f85900361044957604051633ce6169160e11b815260040160405180910390fd5b8342111561046a5760405163b08ce5b360e01b815260040160405180910390fd5b5f81900361048b5760405163166c700d60e21b815260040160405180910390fd5b5f8381526005602052604090205460ff16156104ba57604051630ced304360e01b815260040160405180910390fd5b5f838152600560205260408120805460ff191660011790556104de87878787610a64565b90505f6105208285858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610ba792505050565b6004549091506001600160a01b03808316911614610550576040516282b42960e81b815260040160405180910390fd5b5f5b878110156105e9575f80308b8b8581811061056f5761056f61165c565b90506020028101906105819190611670565b60405161058f9291906116b3565b5f604051808303815f865af19150503d805f81146105c8576040519150601f19603f3d011682016040523d82523d5f602084013e6105cd565b606091505b5091509150816105df57805160208201fd5b5050600101610552565b50604080518881526020810188905290810186905233907f704d392ae0677a1e26b4358b06346bfa8e93d60615e56c3764c867b35c1474639060600160405180910390a250506106396001600355565b505050505050565b6002546001600160a01b0316331480159061065c5750333014155b1561067a5760405163c183bcef60e01b815260040160405180910390fd5b61068f6001600160a01b038316825f19610bc9565b5050565b6002546001600160a01b031633148015906106ae5750333014155b156106cc5760405163c183bcef60e01b815260040160405180910390fd5b6040516370a0823160e01b815230600482015261068f9082906001600160a01b038516906370a0823190602401602060405180830381865afa158015610714573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073891906116c2565b6001600160a01b0385169190610c8a565b6002546001600160a01b031633148015906107645750333014155b156107825760405163c183bcef60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004015f604051808303818588803b1580156107db575f5ffd5b505af1158015610639573d5f5f3e3d5ffd5b6107f561086b565b6001600160a01b03811661085f5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b61086881610911565b50565b6002546001600160a01b031633146103985760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610856565b606061090883835f6040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c65640000815250610cbf565b90505b92915050565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b606060ff831461097c5761097583610d96565b905061090b565b818054610988906116d9565b80601f01602080910402602001604051908101604052809291908181526020018280546109b4906116d9565b80156109ff5780601f106109d6576101008083540402835291602001916109ff565b820191905f5260205f20905b8154815290600101906020018083116109e257829003601f168201915b5050505050905061090b565b600260035403610a5d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610856565b6002600355565b5f808467ffffffffffffffff811115610a7f57610a7f611648565b604051908082528060200260200182016040528015610aa8578160200160208202803683370190505b5090505f5b85811015610b1457868682818110610ac757610ac761165c565b9050602002810190610ad99190611670565b604051610ae79291906116b3565b6040518091039020828281518110610b0157610b0161165c565b6020908102919091010152600101610aad565b50610b9b7fc63ad3fbe0bcd97d53b1a1a90c2d1496c83b7094a6e25814c7e0a8205a2e1c9682604051602001610b4a9190611711565b60408051601f19818403018152828252805160209182012090830193909352810191909152606081018690526080810185905260a00160405160208183030381529060405280519060200120610dd3565b9150505b949350505050565b5f5f5f610bb48585610dff565b91509150610bc181610e41565b509392505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052610c1a8482610f8a565b610381576040516001600160a01b03841660248201525f6044820152610c8090859063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261102b565b610381848261102b565b6040516001600160a01b038316602482015260448101829052610cba90849063a9059cbb60e01b90606401610c49565b505050565b606082471015610d205760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610856565b5f5f866001600160a01b03168587604051610d3b9190611746565b5f6040518083038185875af1925050503d805f8114610d75576040519150601f19603f3d011682016040523d82523d5f602084013e610d7a565b606091505b5091509150610d8b878383876110fe565b979650505050505050565b60605f610da283611176565b6040805160208082528183019092529192505f91906020820181803683375050509182525060208101929092525090565b5f61090b610ddf61119d565b8360405161190160f01b8152600281019290925260228201526042902090565b5f5f8251604103610e33576020830151604084015160608501515f1a610e27878285856112cb565b94509450505050610e3a565b505f905060025b9250929050565b5f816004811115610e5457610e5461175c565b03610e5c5750565b6001816004811115610e7057610e7061175c565b03610ebd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610856565b6002816004811115610ed157610ed161175c565b03610f1e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610856565b6003816004811115610f3257610f3261175c565b036108685760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610856565b5f5f5f846001600160a01b031684604051610fa59190611746565b5f604051808303815f865af19150503d805f8114610fde576040519150601f19603f3d011682016040523d82523d5f602084013e610fe3565b606091505b509150915081801561100d57508051158061100d57508080602001905181019061100d9190611770565b801561102257506001600160a01b0385163b15155b95945050505050565b5f61107f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113889092919063ffffffff16565b905080515f148061109f57508080602001905181019061109f9190611770565b610cba5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610856565b6060831561116c5782515f03611165576001600160a01b0385163b6111655760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610856565b5081610b9f565b610b9f8383611396565b5f60ff8216601f81111561090b57604051632cd44ac360e21b815260040160405180910390fd5b5f306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156111f557507f000000000000000000000000000000000000000000000000000000000000000046145b1561121f57507f000000000000000000000000000000000000000000000000000000000000000090565b6112c6604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b905090565b5f807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561130057505f9050600361137f565b604080515f8082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611351573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116611379575f6001925092505061137f565b91505f90505b94509492505050565b6060610b9f84845f85610cbf565b8151156113a65781518083602001fd5b8060405162461bcd60e51b8152600401610856919061178f565b5f602082840312156113d0575f5ffd5b5035919050565b6001600160a01b0381168114610868575f5ffd5b5f602082840312156113fb575f5ffd5b8135611406816113d7565b9392505050565b5f5f83601f84011261141d575f5ffd5b50813567ffffffffffffffff811115611434575f5ffd5b602083019150836020828501011115610e3a575f5ffd5b5f5f5f6040848603121561145d575f5ffd5b8335611468816113d7565b9250602084013567ffffffffffffffff811115611483575f5ffd5b61148f8682870161140d565b9497909650939450505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60ff60f81b8816815260e060208201525f6114e860e083018961149c565b82810360408401526114fa818961149c565b606084018890526001600160a01b038716608085015260a0840186905283810360c0850152845180825260208087019350909101905f5b8181101561154f578351835260209384019390920191600101611531565b50909b9a5050505050505050505050565b5f5f5f5f5f5f60808789031215611575575f5ffd5b863567ffffffffffffffff81111561158b575f5ffd5b8701601f8101891361159b575f5ffd5b803567ffffffffffffffff8111156115b1575f5ffd5b8960208260051b84010111156115c5575f5ffd5b602091820197509550870135935060408701359250606087013567ffffffffffffffff8111156115f3575f5ffd5b6115ff89828a0161140d565b979a9699509497509295939492505050565b5f5f60408385031215611622575f5ffd5b823561162d816113d7565b9150602083013561163d816113d7565b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112611685575f5ffd5b83018035915067ffffffffffffffff82111561169f575f5ffd5b602001915036819003821315610e3a575f5ffd5b818382375f9101908152919050565b5f602082840312156116d2575f5ffd5b5051919050565b600181811c908216806116ed57607f821691505b60208210810361170b57634e487b7160e01b5f52602260045260245ffd5b50919050565b81515f90829060208501835b8281101561173b57815184526020938401939091019060010161171d565b509195945050505050565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52602160045260245ffd5b5f60208284031215611780575f5ffd5b81518015158114611406575f5ffd5b602081525f610908602083018461149c56fea26469706673582212208ed3d70fc887cfe798b30f662a510ba930e9ad24302c1855d3f33642031380a364736f6c634300081c0033",
  "devdoc": {
    "author": "Venus Protocol",
    "custom:security-contact": "security@venus.io",
    "details": "This contract provides utilities for wrapping native tokens, managing approvals,      and executing arbitrary calls in a single transaction. It supports optional      signature verification using EIP-712 for backend-authorized operations.      All functions except multicall are designed to be called internally via multicall.",
    "errors": {
      "CallerNotAuthorized()": [
        {
          "details": "Only owner or contract itself can call protected functions"
        }
      ],
      "DeadlineReached()": [
        {
          "details": "Emitted when block.timestamp > deadline in multicall"
        }
      ],
      "MissingSignature()": [
        {
          "details": "Emitted when signature length is zero but verification is expected"
        }
      ],
      "NoCallsProvided()": [
        {
          "details": "Emitted when calls array is empty in multicall"
        }
      ],
      "SaltAlreadyUsed()": [
        {
          "details": "Prevents replay attacks by ensuring each salt is used only once"
        }
      ],
      "Unauthorized()": [
        {
          "details": "Emitted when recovered signer doesn't match backendSigner"
        }
      ],
      "ZeroAddress()": [
        {
          "details": "Used in constructor and setBackendSigner validation"
        }
      ]
    },
    "events": {
      "BackendSignerUpdated(address,address)": {
        "params": {
          "newSigner": "New backend signer address",
          "oldSigner": "Previous backend signer address"
        }
      },
      "EIP712DomainChanged()": {
        "details": "MAY be emitted to signal that the domain could have changed."
      },
      "MulticallExecuted(address,uint256,uint256,bytes32)": {
        "params": {
          "caller": "Address that initiated the multicall",
          "callsCount": "Number of calls executed in the batch",
          "deadline": "Deadline timestamp used for the operation",
          "salt": "Salt used for replay protection"
        }
      }
    },
    "kind": "dev",
    "methods": {
      "approveMax(address,address)": {
        "custom:error": "CallerNotAuthorized if caller is not owner or contract itself",
        "custom:security": "Grants unlimited approval - ensure spender is trusted",
        "details": "Sets approval to type(uint256).max for unlimited spendingUses forceApprove to handle tokens that require 0 approval firstShould only be called via multicall",
        "params": {
          "spender": "Address to grant approval to",
          "token": "ERC-20 token contract to approve"
        }
      },
      "constructor": {
        "custom:error": "ZeroAddress if wrappedNative_ is address(0)ZeroAddress if backendSigner_ is address(0)",
        "details": "Initializes EIP-712 domain with name \"VenusSwap\" and version \"1\"Transfers ownership to msg.senderReverts with ZeroAddress if either parameter is address(0)",
        "params": {
          "backendSigner_": "Address authorized to sign multicall operations",
          "wrappedNative_": "Address of the wrapped native asset contract"
        }
      },
      "eip712Domain()": {
        "details": "See {EIP-5267}. _Available since v4.9._"
      },
      "genericCall(address,bytes)": {
        "custom:error": "CallerNotAuthorized if caller is not owner or contract itself",
        "custom:security": "Use with extreme caution - can call any contract with any dataEnsure proper validation of target and data in off-chain systems",
        "details": "This function can interact with any external contractShould only be called via multicall for safety",
        "params": {
          "data": "Encoded function call data",
          "target": "Address of the contract to call"
        }
      },
      "multicall(bytes[],uint256,bytes32,bytes)": {
        "custom:error": "NoCallsProvided if calls array is emptyDeadlineReached if block.timestamp > deadlineSaltAlreadyUsed if salt has been used beforeUnauthorized if signature verification fails",
        "custom:security": "Only the contract itself can call wrap, sweep, approveMax, and genericCall",
        "details": "All calls are executed atomically - if any call fails, entire transaction revertsCalls must be to functions on this contract (address(this))Signature verification is only performed if signature.length != 0Protected by nonReentrant modifier to prevent reentrancy attacksEmits MulticallExecuted event upon successful execution",
        "params": {
          "calls": "Array of encoded function calls to execute on this contract",
          "deadline": "Unix timestamp after which the transaction will revert",
          "salt": "Unique value to ensure this exact multicall can only be executed once",
          "signature": "Optional EIP-712 signature from backend signer (empty bytes to skip verification)"
        }
      },
      "owner()": {
        "details": "Returns the address of the current owner."
      },
      "renounceOwnership()": {
        "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner."
      },
      "setBackendSigner(address)": {
        "custom:error": "ZeroAddress if newSigner is address(0)Ownable: caller is not the owner (from OpenZeppelin Ownable)",
        "details": "Only callable by contract ownerReverts with ZeroAddress if newSigner is address(0)Emits BackendSignerUpdated event",
        "params": {
          "newSigner": "New backend signer address"
        }
      },
      "sweep(address,address)": {
        "custom:error": "CallerNotAuthorized if caller is not owner or contract itself",
        "details": "Transfers the entire balance of token held by this contractUses SafeERC20 for safe transfer operationsShould only be called via multicall",
        "params": {
          "to": "Recipient address for the swept tokens",
          "token": "ERC-20 token contract to sweep"
        }
      },
      "transferOwnership(address)": {
        "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner."
      },
      "wrap(uint256)": {
        "custom:error": "CallerNotAuthorized if caller is not owner or contract itself",
        "custom:security": "Ensure msg.value matches amount parameter",
        "details": "Calls deposit() on WRAPPED_NATIVE contract with msg.valueWrapped tokens remain in this contract until sweptShould only be called via multicall",
        "params": {
          "amount": "Amount of native asset to wrap (must match msg.value)"
        }
      }
    },
    "stateVariables": {
      "MULTICALL_TYPEHASH": {
        "details": "keccak256(\"Multicall(bytes[] calls,uint256 deadline,bytes32 salt)\")"
      },
      "backendSigner": {
        "details": "Can be updated by contract owner via setBackendSigner"
      },
      "usedSalts": {
        "details": "Maps salt => bool to prevent reuse of same salt"
      }
    },
    "title": "SwapHelper",
    "version": 1
  },
  "userdoc": {
    "errors": {
      "CallerNotAuthorized()": [
        {
          "notice": "Error thrown when caller is not authorized"
        }
      ],
      "DeadlineReached()": [
        {
          "notice": "Error thrown when transaction deadline has passed"
        }
      ],
      "MissingSignature()": [
        {
          "notice": "Error thrown when signature is missing but required"
        }
      ],
      "NoCallsProvided()": [
        {
          "notice": "Error thrown when no calls are provided to multicall"
        }
      ],
      "SaltAlreadyUsed()": [
        {
          "notice": "Error thrown when salt has already been used"
        }
      ],
      "Unauthorized()": [
        {
          "notice": "Error thrown when signature verification fails"
        }
      ],
      "ZeroAddress()": [
        {
          "notice": "Error thrown when zero address is provided as parameter"
        }
      ]
    },
    "events": {
      "BackendSignerUpdated(address,address)": {
        "notice": "Event emitted when backend signer is updated"
      },
      "MulticallExecuted(address,uint256,uint256,bytes32)": {
        "notice": "Event emitted when multicall is successfully executed"
      }
    },
    "kind": "user",
    "methods": {
      "WRAPPED_NATIVE()": {
        "notice": "Wrapped native asset contract (e.g., WBNB, WETH)"
      },
      "approveMax(address,address)": {
        "notice": "Approves maximum amount of an ERC-20 token to a specified spender"
      },
      "backendSigner()": {
        "notice": "Address authorized to sign multicall operations"
      },
      "constructor": {
        "notice": "Constructor"
      },
      "genericCall(address,bytes)": {
        "notice": "Generic call function to execute a call to an arbitrary address"
      },
      "multicall(bytes[],uint256,bytes32,bytes)": {
        "notice": "Multicall function to execute multiple calls in a single transaction"
      },
      "setBackendSigner(address)": {
        "notice": "Updates the backend signer address"
      },
      "sweep(address,address)": {
        "notice": "Sweeps entire balance of an ERC-20 token to a specified address"
      },
      "usedSalts(bytes32)": {
        "notice": "Mapping to track used salts for replay protection"
      },
      "wrap(uint256)": {
        "notice": "Wraps native asset into an ERC-20 wrapped token"
      }
    },
    "notice": "Helper contract for executing multiple token operations atomically",
    "version": 1
  },
  "storageLayout": {
    "storage": [
      {
        "astId": 2006,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "_nameFallback",
        "offset": 0,
        "slot": "0",
        "type": "t_string_storage"
      },
      {
        "astId": 2008,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "_versionFallback",
        "offset": 0,
        "slot": "1",
        "type": "t_string_storage"
      },
      {
        "astId": 827,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "_owner",
        "offset": 0,
        "slot": "2",
        "type": "t_address"
      },
      {
        "astId": 968,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "_status",
        "offset": 0,
        "slot": "3",
        "type": "t_uint256"
      },
      {
        "astId": 3479,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "backendSigner",
        "offset": 0,
        "slot": "4",
        "type": "t_address"
      },
      {
        "astId": 3484,
        "contract": "contracts/SwapHelper/SwapHelper.sol:SwapHelper",
        "label": "usedSalts",
        "offset": 0,
        "slot": "5",
        "type": "t_mapping(t_bytes32,t_bool)"
      }
    ],
    "types": {
      "t_address": {
        "encoding": "inplace",
        "label": "address",
        "numberOfBytes": "20"
      },
      "t_bool": {
        "encoding": "inplace",
        "label": "bool",
        "numberOfBytes": "1"
      },
      "t_bytes32": {
        "encoding": "inplace",
        "label": "bytes32",
        "numberOfBytes": "32"
      },
      "t_mapping(t_bytes32,t_bool)": {
        "encoding": "mapping",
        "key": "t_bytes32",
        "label": "mapping(bytes32 => bool)",
        "numberOfBytes": "32",
        "value": "t_bool"
      },
      "t_string_storage": {
        "encoding": "bytes",
        "label": "string",
        "numberOfBytes": "32"
      },
      "t_uint256": {
        "encoding": "inplace",
        "label": "uint256",
        "numberOfBytes": "32"
      }
    }
  }
}
