creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@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"
      },
      "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n// EIP-2612 is Final as of 2022-11-01. This file is deprecated.\n\nimport \"./ERC20Permit.sol\";\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/cryptography/EIP712.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation 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 * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n    using Counters for Counters.Counter;\n\n    mapping(address => Counters.Counter) private _nonces;\n\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private constant _PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n    /**\n     * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n     * However, to ensure consistency with the upgradeable transpiler, we will continue\n     * to reserve a slot.\n     * @custom:oz-renamed-from _PERMIT_TYPEHASH\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n    /**\n     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n     *\n     * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n     */\n    constructor(string memory name) EIP712(name, \"1\") {}\n\n    /**\n     * @dev See {IERC20Permit-permit}.\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    ) public virtual override {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n        bytes32 hash = _hashTypedDataV4(structHash);\n\n        address signer = ECDSA.recover(hash, v, r, s);\n        require(signer == owner, \"ERC20Permit: invalid signature\");\n\n        _approve(owner, spender, value);\n    }\n\n    /**\n     * @dev See {IERC20Permit-nonces}.\n     */\n    function nonces(address owner) public view virtual override returns (uint256) {\n        return _nonces[owner].current();\n    }\n\n    /**\n     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n        return _domainSeparatorV4();\n    }\n\n    /**\n     * @dev \"Consume a nonce\": return the current value and increment.\n     *\n     * _Available since v4.1._\n     */\n    function _useNonce(address owner) internal virtual returns (uint256 current) {\n        Counters.Counter storage nonce = _nonces[owner];\n        current = nonce.current();\n        nonce.increment();\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (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 */\ninterface IERC20Permit {\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    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"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.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 IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the 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"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.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 \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.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 SafeERC20 {\n    using Address 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(IERC20 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(IERC20 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(IERC20 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(IERC20 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(IERC20 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(IERC20 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        IERC20Permit 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(IERC20 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(IERC20 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))) && Address.isContract(address(token));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.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 Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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"
      },
      "@openzeppelin/contracts/utils/Counters.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n    struct Counter {\n        // This variable should never be directly accessed by users of the library: interactions must be restricted to\n        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n        // this feature: see https://github.com/ethereum/solidity/issues/4637\n        uint256 _value; // default: 0\n    }\n\n    function current(Counter storage counter) internal view returns (uint256) {\n        return counter._value;\n    }\n\n    function increment(Counter storage counter) internal {\n        unchecked {\n            counter._value += 1;\n        }\n    }\n\n    function decrement(Counter storage counter) internal {\n        uint256 value = counter._value;\n        require(value > 0, \"Counter: decrement overflow\");\n        unchecked {\n            counter._value = value - 1;\n        }\n    }\n\n    function reset(Counter storage counter) internal {\n        counter._value = 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\n// EIP-712 is Final as of 2022-08-11. This file is deprecated.\n\nimport \"./EIP712.sol\";\n"
      },
      "@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 ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        /// @solidity memory-safe-assembly\n        assembly {\n            mstore(0x00, \"\\x19Ethereum Signed Message:\\n32\")\n            mstore(0x1c, hash)\n            message := keccak256(0x00, 0x3c)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, \"\\x19\\x01\")\n            mstore(add(ptr, 0x02), domainSeparator)\n            mstore(add(ptr, 0x22), structHash)\n            data := keccak256(ptr, 0x42)\n        }\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Data with intended validator, created from a\n     * `validator` and `data` according to the version 0 of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x00\", validator, data));\n    }\n}\n"
      },
      "@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"
      },
      "@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        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `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"
      },
      "@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"
      },
      "@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"
      },
      "@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"
      },
      "@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"
      },
      "contracts/pendle/contracts/core/erc20/PendleERC20.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/utils/Context.sol\";\n\n/**\n * @dev Pendle's ERC20 implementation, modified from @openzeppelin implementation\n * Changes are:\n * - comes with built-in reentrancy protection, storage-packed with totalSupply variable\n * - delete increaseAllowance / decreaseAllowance\n * - add nonReentrancy protection to transfer / transferFrom functions\n * - allow decimals to be passed in\n * - block self-transfer by default\n */\n// solhint-disable\ncontract PendleERC20 is Context, IERC20, IERC20Metadata {\n    uint8 private constant _NOT_ENTERED = 1;\n    uint8 private constant _ENTERED = 2;\n\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint248 private _totalSupply;\n    uint8 private _status;\n\n    string private _name;\n    string private _symbol;\n    uint8 public immutable decimals;\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        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\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 Sets the values for {name}, {symbol} and {decimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) {\n        _name = name_;\n        _symbol = symbol_;\n        decimals = decimals_;\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) external virtual override nonReentrant returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) external virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external virtual override nonReentrant returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n        require(from != to, \"ERC20: transfer to self\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n        }\n        _balances[to] += amount;\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += toUint248(amount);\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= toUint248(amount);\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    function toUint248(uint256 x) internal virtual returns (uint248) {\n        require(x <= type(uint248).max); // signed, lim = bit-1\n        return uint248(x);\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/erc20/PendleERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./PendleERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/utils/Context.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/utils/Counters.sol\";\n\n/// @dev forked from OZ's ERC20Permit\ncontract PendleERC20Permit is PendleERC20, IERC20Permit, EIP712 {\n    using Counters for Counters.Counter;\n\n    mapping(address => Counters.Counter) private _nonces;\n\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private constant _PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        uint8 decimals_\n    ) PendleERC20(name_, symbol_, decimals_) EIP712(name_, \"1\") {}\n\n    /**\n     * @dev See {IERC20Permit-permit}.\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    ) public virtual override {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n        bytes32 hash = _hashTypedDataV4(structHash);\n\n        address signer = ECDSA.recover(hash, v, r, s);\n        require(signer == owner, \"ERC20Permit: invalid signature\");\n\n        _approve(owner, spender, value);\n    }\n\n    /**\n     * @dev See {IERC20Permit-nonces}.\n     */\n    function nonces(address owner) public view virtual override returns (uint256) {\n        return _nonces[owner].current();\n    }\n\n    /**\n     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n        return _domainSeparatorV4();\n    }\n\n    /**\n     * @dev \"Consume a nonce\": return the current value and increment.\n     *\n     * _Available since v4.1._\n     */\n    function _useNonce(address owner) internal virtual returns (uint256 current) {\n        Counters.Counter storage nonce = _nonces[owner];\n        current = nonce.current();\n        nonce.increment();\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/ArrayLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nlibrary ArrayLib {\n    function sum(uint256[] memory input) internal pure returns (uint256) {\n        uint256 value = 0;\n        for (uint256 i = 0; i < input.length; ) {\n            value += input[i];\n            unchecked {\n                i++;\n            }\n        }\n        return value;\n    }\n\n    /// @notice return index of the element if found, else return uint256.max\n    function find(address[] memory array, address element) internal pure returns (uint256 index) {\n        uint256 length = array.length;\n        for (uint256 i = 0; i < length; ) {\n            if (array[i] == element) return i;\n            unchecked {\n                i++;\n            }\n        }\n        return type(uint256).max;\n    }\n\n    function append(address[] memory inp, address element) internal pure returns (address[] memory out) {\n        uint256 length = inp.length;\n        out = new address[](length + 1);\n        for (uint256 i = 0; i < length; ) {\n            out[i] = inp[i];\n            unchecked {\n                i++;\n            }\n        }\n        out[length] = element;\n    }\n\n    /**\n     * @dev This function assumes a and b each contains unidentical elements\n     * @param a array of addresses a\n     * @param b array of addresses b\n     * @return out Concatenation of a and b containing unidentical elements\n     */\n    function merge(address[] memory a, address[] memory b) internal pure returns (address[] memory out) {\n        unchecked {\n            uint256 countUnidenticalB = 0;\n            bool[] memory isUnidentical = new bool[](b.length);\n            for (uint256 i = 0; i < b.length; ++i) {\n                if (!contains(a, b[i])) {\n                    countUnidenticalB++;\n                    isUnidentical[i] = true;\n                }\n            }\n\n            out = new address[](a.length + countUnidenticalB);\n            for (uint256 i = 0; i < a.length; ++i) {\n                out[i] = a[i];\n            }\n            uint256 id = a.length;\n            for (uint256 i = 0; i < b.length; ++i) {\n                if (isUnidentical[i]) {\n                    out[id++] = b[i];\n                }\n            }\n        }\n    }\n\n    // various version of contains\n    function contains(address[] memory array, address element) internal pure returns (bool) {\n        uint256 length = array.length;\n        for (uint256 i = 0; i < length; ) {\n            if (array[i] == element) return true;\n            unchecked {\n                i++;\n            }\n        }\n        return false;\n    }\n\n    function contains(bytes4[] memory array, bytes4 element) internal pure returns (bool) {\n        uint256 length = array.length;\n        for (uint256 i = 0; i < length; ) {\n            if (array[i] == element) return true;\n            unchecked {\n                i++;\n            }\n        }\n        return false;\n    }\n\n    function create(address a) internal pure returns (address[] memory res) {\n        res = new address[](1);\n        res[0] = a;\n    }\n\n    function create(address a, address b) internal pure returns (address[] memory res) {\n        res = new address[](2);\n        res[0] = a;\n        res[1] = b;\n    }\n\n    function create(uint256 a) internal pure returns (uint256[] memory res) {\n        res = new uint256[](1);\n        res[0] = a;\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/Errors.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nlibrary Errors {\n    // BulkSeller\n    error BulkInsufficientSyForTrade(uint256 currentAmount, uint256 requiredAmount);\n    error BulkInsufficientTokenForTrade(uint256 currentAmount, uint256 requiredAmount);\n    error BulkInSufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut);\n    error BulkInSufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);\n    error BulkInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance);\n    error BulkNotMaintainer();\n    error BulkNotAdmin();\n    error BulkSellerAlreadyExisted(address token, address SY, address bulk);\n    error BulkSellerInvalidToken(address token, address SY);\n    error BulkBadRateTokenToSy(uint256 actualRate, uint256 currentRate, uint256 eps);\n    error BulkBadRateSyToToken(uint256 actualRate, uint256 currentRate, uint256 eps);\n\n    // APPROX\n    error ApproxFail();\n    error ApproxParamsInvalid(uint256 guessMin, uint256 guessMax, uint256 eps);\n    error ApproxBinarySearchInputInvalid(\n        uint256 approxGuessMin,\n        uint256 approxGuessMax,\n        uint256 minGuessMin,\n        uint256 maxGuessMax\n    );\n\n    // MARKET + MARKET MATH CORE\n    error MarketExpired();\n    error MarketZeroAmountsInput();\n    error MarketZeroAmountsOutput();\n    error MarketZeroLnImpliedRate();\n    error MarketInsufficientPtForTrade(int256 currentAmount, int256 requiredAmount);\n    error MarketInsufficientPtReceived(uint256 actualBalance, uint256 requiredBalance);\n    error MarketInsufficientSyReceived(uint256 actualBalance, uint256 requiredBalance);\n    error MarketZeroTotalPtOrTotalAsset(int256 totalPt, int256 totalAsset);\n    error MarketExchangeRateBelowOne(int256 exchangeRate);\n    error MarketProportionMustNotEqualOne();\n    error MarketRateScalarBelowZero(int256 rateScalar);\n    error MarketScalarRootBelowZero(int256 scalarRoot);\n    error MarketProportionTooHigh(int256 proportion, int256 maxProportion);\n\n    error OracleUninitialized();\n    error OracleTargetTooOld(uint32 target, uint32 oldest);\n    error OracleZeroCardinality();\n\n    error MarketFactoryExpiredPt();\n    error MarketFactoryInvalidPt();\n    error MarketFactoryMarketExists();\n\n    error MarketFactoryLnFeeRateRootTooHigh(uint80 lnFeeRateRoot, uint256 maxLnFeeRateRoot);\n    error MarketFactoryOverriddenFeeTooHigh(uint80 overriddenFee, uint256 marketLnFeeRateRoot);\n    error MarketFactoryReserveFeePercentTooHigh(uint8 reserveFeePercent, uint8 maxReserveFeePercent);\n    error MarketFactoryZeroTreasury();\n    error MarketFactoryInitialAnchorTooLow(int256 initialAnchor, int256 minInitialAnchor);\n    error MFNotPendleMarket(address addr);\n\n    // ROUTER\n    error RouterInsufficientLpOut(uint256 actualLpOut, uint256 requiredLpOut);\n    error RouterInsufficientSyOut(uint256 actualSyOut, uint256 requiredSyOut);\n    error RouterInsufficientPtOut(uint256 actualPtOut, uint256 requiredPtOut);\n    error RouterInsufficientYtOut(uint256 actualYtOut, uint256 requiredYtOut);\n    error RouterInsufficientPYOut(uint256 actualPYOut, uint256 requiredPYOut);\n    error RouterInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);\n    error RouterInsufficientSyRepay(uint256 actualSyRepay, uint256 requiredSyRepay);\n    error RouterInsufficientPtRepay(uint256 actualPtRepay, uint256 requiredPtRepay);\n    error RouterNotAllSyUsed(uint256 netSyDesired, uint256 netSyUsed);\n\n    error RouterTimeRangeZero();\n    error RouterCallbackNotPendleMarket(address caller);\n    error RouterInvalidAction(bytes4 selector);\n    error RouterInvalidFacet(address facet);\n\n    error RouterKyberSwapDataZero();\n\n    error SimulationResults(bool success, bytes res);\n\n    // YIELD CONTRACT\n    error YCExpired();\n    error YCNotExpired();\n    error YieldContractInsufficientSy(uint256 actualSy, uint256 requiredSy);\n    error YCNothingToRedeem();\n    error YCPostExpiryDataNotSet();\n    error YCNoFloatingSy();\n\n    // YieldFactory\n    error YCFactoryInvalidExpiry();\n    error YCFactoryYieldContractExisted();\n    error YCFactoryZeroExpiryDivisor();\n    error YCFactoryZeroTreasury();\n    error YCFactoryInterestFeeRateTooHigh(uint256 interestFeeRate, uint256 maxInterestFeeRate);\n    error YCFactoryRewardFeeRateTooHigh(uint256 newRewardFeeRate, uint256 maxRewardFeeRate);\n\n    // SY\n    error SYInvalidTokenIn(address token);\n    error SYInvalidTokenOut(address token);\n    error SYZeroDeposit();\n    error SYZeroRedeem();\n    error SYInsufficientSharesOut(uint256 actualSharesOut, uint256 requiredSharesOut);\n    error SYInsufficientTokenOut(uint256 actualTokenOut, uint256 requiredTokenOut);\n\n    // SY-specific\n    error SYQiTokenMintFailed(uint256 errCode);\n    error SYQiTokenRedeemFailed(uint256 errCode);\n    error SYQiTokenRedeemRewardsFailed(uint256 rewardAccruedType0, uint256 rewardAccruedType1);\n    error SYQiTokenBorrowRateTooHigh(uint256 borrowRate, uint256 borrowRateMax);\n\n    error SYCurveInvalidPid();\n    error SYCurve3crvPoolNotFound();\n\n    error SYApeDepositAmountTooSmall(uint256 amountDeposited);\n    error SYBalancerInvalidPid();\n    error SYInvalidRewardToken(address token);\n\n    error SYStargateRedeemCapExceeded(uint256 amountLpDesired, uint256 amountLpRedeemable);\n\n    error SYBalancerReentrancy();\n\n    error NotFromTrustedRemote(uint16 srcChainId, bytes path);\n\n    // Liquidity Mining\n    error VCInactivePool(address pool);\n    error VCPoolAlreadyActive(address pool);\n    error VCZeroVePendle(address user);\n    error VCExceededMaxWeight(uint256 totalWeight, uint256 maxWeight);\n    error VCEpochNotFinalized(uint256 wTime);\n    error VCPoolAlreadyAddAndRemoved(address pool);\n\n    error VEInvalidNewExpiry(uint256 newExpiry);\n    error VEExceededMaxLockTime();\n    error VEInsufficientLockTime();\n    error VENotAllowedReduceExpiry();\n    error VEZeroAmountLocked();\n    error VEPositionNotExpired();\n    error VEZeroPosition();\n    error VEZeroSlope(uint128 bias, uint128 slope);\n    error VEReceiveOldSupply(uint256 msgTime);\n\n    error GCNotPendleMarket(address caller);\n    error GCNotVotingController(address caller);\n\n    error InvalidWTime(uint256 wTime);\n    error ExpiryInThePast(uint256 expiry);\n    error ChainNotSupported(uint256 chainId);\n\n    error FDTotalAmountFundedNotMatch(uint256 actualTotalAmount, uint256 expectedTotalAmount);\n    error FDEpochLengthMismatch();\n    error FDInvalidPool(address pool);\n    error FDPoolAlreadyExists(address pool);\n    error FDInvalidNewFinishedEpoch(uint256 oldFinishedEpoch, uint256 newFinishedEpoch);\n    error FDInvalidStartEpoch(uint256 startEpoch);\n    error FDInvalidWTimeFund(uint256 lastFunded, uint256 wTime);\n    error FDFutureFunding(uint256 lastFunded, uint256 currentWTime);\n\n    error BDInvalidEpoch(uint256 epoch, uint256 startTime);\n\n    // Cross-Chain\n    error MsgNotFromSendEndpoint(uint16 srcChainId, bytes path);\n    error MsgNotFromReceiveEndpoint(address sender);\n    error InsufficientFeeToSendMsg(uint256 currentFee, uint256 requiredFee);\n    error ApproxDstExecutionGasNotSet();\n    error InvalidRetryData();\n\n    // GENERIC MSG\n    error ArrayLengthMismatch();\n    error ArrayEmpty();\n    error ArrayOutOfBounds();\n    error ZeroAddress();\n    error FailedToSendEther();\n    error InvalidMerkleProof();\n\n    error OnlyLayerZeroEndpoint();\n    error OnlyYT();\n    error OnlyYCFactory();\n    error OnlyWhitelisted();\n\n    // Swap Aggregator\n    error SAInsufficientTokenIn(address tokenIn, uint256 amountExpected, uint256 amountActual);\n    error UnsupportedSelector(uint256 aggregatorType, bytes4 selector);\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/math/LogExpMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\n// documentation files (the “Software”), to deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to\n// permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\n// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the\n// Software.\n\n// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\npragma solidity ^0.8.0;\n\n/* solhint-disable */\n\n/**\n * @dev Exponentiation and logarithm functions for 18 decimal fixed point numbers (both base and exponent/argument).\n *\n * Exponentiation and logarithm with arbitrary bases (x^y and log_x(y)) are implemented by conversion to natural\n * exponentiation and logarithm (where the base is Euler's number).\n *\n * @author Fernando Martinelli - @fernandomartinelli\n * @author Sergio Yuhjtman - @sergioyuhjtman\n * @author Daniel Fernandez - @dmf7z\n */\nlibrary LogExpMath {\n    // All fixed point multiplications and divisions are inlined. This means we need to divide by ONE when multiplying\n    // two numbers, and multiply by ONE when dividing them.\n\n    // All arguments and return values are 18 decimal fixed point numbers.\n    int256 constant ONE_18 = 1e18;\n\n    // Internally, intermediate values are computed with higher precision as 20 decimal fixed point numbers, and in the\n    // case of ln36, 36 decimals.\n    int256 constant ONE_20 = 1e20;\n    int256 constant ONE_36 = 1e36;\n\n    // The domain of natural exponentiation is bound by the word size and number of decimals used.\n    //\n    // Because internally the result will be stored using 20 decimals, the largest possible result is\n    // (2^255 - 1) / 10^20, which makes the largest exponent ln((2^255 - 1) / 10^20) = 130.700829182905140221.\n    // The smallest possible result is 10^(-18), which makes largest negative argument\n    // ln(10^(-18)) = -41.446531673892822312.\n    // We use 130.0 and -41.0 to have some safety margin.\n    int256 constant MAX_NATURAL_EXPONENT = 130e18;\n    int256 constant MIN_NATURAL_EXPONENT = -41e18;\n\n    // Bounds for ln_36's argument. Both ln(0.9) and ln(1.1) can be represented with 36 decimal places in a fixed point\n    // 256 bit integer.\n    int256 constant LN_36_LOWER_BOUND = ONE_18 - 1e17;\n    int256 constant LN_36_UPPER_BOUND = ONE_18 + 1e17;\n\n    uint256 constant MILD_EXPONENT_BOUND = 2 ** 254 / uint256(ONE_20);\n\n    // 18 decimal constants\n    int256 constant x0 = 128000000000000000000; // 2ˆ7\n    int256 constant a0 = 38877084059945950922200000000000000000000000000000000000; // eˆ(x0) (no decimals)\n    int256 constant x1 = 64000000000000000000; // 2ˆ6\n    int256 constant a1 = 6235149080811616882910000000; // eˆ(x1) (no decimals)\n\n    // 20 decimal constants\n    int256 constant x2 = 3200000000000000000000; // 2ˆ5\n    int256 constant a2 = 7896296018268069516100000000000000; // eˆ(x2)\n    int256 constant x3 = 1600000000000000000000; // 2ˆ4\n    int256 constant a3 = 888611052050787263676000000; // eˆ(x3)\n    int256 constant x4 = 800000000000000000000; // 2ˆ3\n    int256 constant a4 = 298095798704172827474000; // eˆ(x4)\n    int256 constant x5 = 400000000000000000000; // 2ˆ2\n    int256 constant a5 = 5459815003314423907810; // eˆ(x5)\n    int256 constant x6 = 200000000000000000000; // 2ˆ1\n    int256 constant a6 = 738905609893065022723; // eˆ(x6)\n    int256 constant x7 = 100000000000000000000; // 2ˆ0\n    int256 constant a7 = 271828182845904523536; // eˆ(x7)\n    int256 constant x8 = 50000000000000000000; // 2ˆ-1\n    int256 constant a8 = 164872127070012814685; // eˆ(x8)\n    int256 constant x9 = 25000000000000000000; // 2ˆ-2\n    int256 constant a9 = 128402541668774148407; // eˆ(x9)\n    int256 constant x10 = 12500000000000000000; // 2ˆ-3\n    int256 constant a10 = 113314845306682631683; // eˆ(x10)\n    int256 constant x11 = 6250000000000000000; // 2ˆ-4\n    int256 constant a11 = 106449445891785942956; // eˆ(x11)\n\n    /**\n     * @dev Natural exponentiation (e^x) with signed 18 decimal fixed point exponent.\n     *\n     * Reverts if `x` is smaller than MIN_NATURAL_EXPONENT, or larger than `MAX_NATURAL_EXPONENT`.\n     */\n    function exp(int256 x) internal pure returns (int256) {\n        unchecked {\n            require(x >= MIN_NATURAL_EXPONENT && x <= MAX_NATURAL_EXPONENT, \"Invalid exponent\");\n\n            if (x < 0) {\n                // We only handle positive exponents: e^(-x) is computed as 1 / e^x. We can safely make x positive since it\n                // fits in the signed 256 bit range (as it is larger than MIN_NATURAL_EXPONENT).\n                // Fixed point division requires multiplying by ONE_18.\n                return ((ONE_18 * ONE_18) / exp(-x));\n            }\n\n            // First, we use the fact that e^(x+y) = e^x * e^y to decompose x into a sum of powers of two, which we call x_n,\n            // where x_n == 2^(7 - n), and e^x_n = a_n has been precomputed. We choose the first x_n, x0, to equal 2^7\n            // because all larger powers are larger than MAX_NATURAL_EXPONENT, and therefore not present in the\n            // decomposition.\n            // At the end of this process we will have the product of all e^x_n = a_n that apply, and the remainder of this\n            // decomposition, which will be lower than the smallest x_n.\n            // exp(x) = k_0 * a_0 * k_1 * a_1 * ... + k_n * a_n * exp(remainder), where each k_n equals either 0 or 1.\n            // We mutate x by subtracting x_n, making it the remainder of the decomposition.\n\n            // The first two a_n (e^(2^7) and e^(2^6)) are too large if stored as 18 decimal numbers, and could cause\n            // intermediate overflows. Instead we store them as plain integers, with 0 decimals.\n            // Additionally, x0 + x1 is larger than MAX_NATURAL_EXPONENT, which means they will not both be present in the\n            // decomposition.\n\n            // For each x_n, we test if that term is present in the decomposition (if x is larger than it), and if so deduct\n            // it and compute the accumulated product.\n\n            int256 firstAN;\n            if (x >= x0) {\n                x -= x0;\n                firstAN = a0;\n            } else if (x >= x1) {\n                x -= x1;\n                firstAN = a1;\n            } else {\n                firstAN = 1; // One with no decimal places\n            }\n\n            // We now transform x into a 20 decimal fixed point number, to have enhanced precision when computing the\n            // smaller terms.\n            x *= 100;\n\n            // `product` is the accumulated product of all a_n (except a0 and a1), which starts at 20 decimal fixed point\n            // one. Recall that fixed point multiplication requires dividing by ONE_20.\n            int256 product = ONE_20;\n\n            if (x >= x2) {\n                x -= x2;\n                product = (product * a2) / ONE_20;\n            }\n            if (x >= x3) {\n                x -= x3;\n                product = (product * a3) / ONE_20;\n            }\n            if (x >= x4) {\n                x -= x4;\n                product = (product * a4) / ONE_20;\n            }\n            if (x >= x5) {\n                x -= x5;\n                product = (product * a5) / ONE_20;\n            }\n            if (x >= x6) {\n                x -= x6;\n                product = (product * a6) / ONE_20;\n            }\n            if (x >= x7) {\n                x -= x7;\n                product = (product * a7) / ONE_20;\n            }\n            if (x >= x8) {\n                x -= x8;\n                product = (product * a8) / ONE_20;\n            }\n            if (x >= x9) {\n                x -= x9;\n                product = (product * a9) / ONE_20;\n            }\n\n            // x10 and x11 are unnecessary here since we have high enough precision already.\n\n            // Now we need to compute e^x, where x is small (in particular, it is smaller than x9). We use the Taylor series\n            // expansion for e^x: 1 + x + (x^2 / 2!) + (x^3 / 3!) + ... + (x^n / n!).\n\n            int256 seriesSum = ONE_20; // The initial one in the sum, with 20 decimal places.\n            int256 term; // Each term in the sum, where the nth term is (x^n / n!).\n\n            // The first term is simply x.\n            term = x;\n            seriesSum += term;\n\n            // Each term (x^n / n!) equals the previous one times x, divided by n. Since x is a fixed point number,\n            // multiplying by it requires dividing by ONE_20, but dividing by the non-fixed point n values does not.\n\n            term = ((term * x) / ONE_20) / 2;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 3;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 4;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 5;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 6;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 7;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 8;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 9;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 10;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 11;\n            seriesSum += term;\n\n            term = ((term * x) / ONE_20) / 12;\n            seriesSum += term;\n\n            // 12 Taylor terms are sufficient for 18 decimal precision.\n\n            // We now have the first a_n (with no decimals), and the product of all other a_n present, and the Taylor\n            // approximation of the exponentiation of the remainder (both with 20 decimals). All that remains is to multiply\n            // all three (one 20 decimal fixed point multiplication, dividing by ONE_20, and one integer multiplication),\n            // and then drop two digits to return an 18 decimal value.\n\n            return (((product * seriesSum) / ONE_20) * firstAN) / 100;\n        }\n    }\n\n    /**\n     * @dev Natural logarithm (ln(a)) with signed 18 decimal fixed point argument.\n     */\n    function ln(int256 a) internal pure returns (int256) {\n        unchecked {\n            // The real natural logarithm is not defined for negative numbers or zero.\n            require(a > 0, \"out of bounds\");\n            if (LN_36_LOWER_BOUND < a && a < LN_36_UPPER_BOUND) {\n                return _ln_36(a) / ONE_18;\n            } else {\n                return _ln(a);\n            }\n        }\n    }\n\n    /**\n     * @dev Exponentiation (x^y) with unsigned 18 decimal fixed point base and exponent.\n     *\n     * Reverts if ln(x) * y is smaller than `MIN_NATURAL_EXPONENT`, or larger than `MAX_NATURAL_EXPONENT`.\n     */\n    function pow(uint256 x, uint256 y) internal pure returns (uint256) {\n        unchecked {\n            if (y == 0) {\n                // We solve the 0^0 indetermination by making it equal one.\n                return uint256(ONE_18);\n            }\n\n            if (x == 0) {\n                return 0;\n            }\n\n            // Instead of computing x^y directly, we instead rely on the properties of logarithms and exponentiation to\n            // arrive at that r`esult. In particular, exp(ln(x)) = x, and ln(x^y) = y * ln(x). This means\n            // x^y = exp(y * ln(x)).\n\n            // The ln function takes a signed value, so we need to make sure x fits in the signed 256 bit range.\n            require(x < 2 ** 255, \"x out of bounds\");\n            int256 x_int256 = int256(x);\n\n            // We will compute y * ln(x) in a single step. Depending on the value of x, we can either use ln or ln_36. In\n            // both cases, we leave the division by ONE_18 (due to fixed point multiplication) to the end.\n\n            // This prevents y * ln(x) from overflowing, and at the same time guarantees y fits in the signed 256 bit range.\n            require(y < MILD_EXPONENT_BOUND, \"y out of bounds\");\n            int256 y_int256 = int256(y);\n\n            int256 logx_times_y;\n            if (LN_36_LOWER_BOUND < x_int256 && x_int256 < LN_36_UPPER_BOUND) {\n                int256 ln_36_x = _ln_36(x_int256);\n\n                // ln_36_x has 36 decimal places, so multiplying by y_int256 isn't as straightforward, since we can't just\n                // bring y_int256 to 36 decimal places, as it might overflow. Instead, we perform two 18 decimal\n                // multiplications and add the results: one with the first 18 decimals of ln_36_x, and one with the\n                // (downscaled) last 18 decimals.\n                logx_times_y = ((ln_36_x / ONE_18) * y_int256 + ((ln_36_x % ONE_18) * y_int256) / ONE_18);\n            } else {\n                logx_times_y = _ln(x_int256) * y_int256;\n            }\n            logx_times_y /= ONE_18;\n\n            // Finally, we compute exp(y * ln(x)) to arrive at x^y\n            require(\n                MIN_NATURAL_EXPONENT <= logx_times_y && logx_times_y <= MAX_NATURAL_EXPONENT,\n                \"product out of bounds\"\n            );\n\n            return uint256(exp(logx_times_y));\n        }\n    }\n\n    /**\n     * @dev Internal natural logarithm (ln(a)) with signed 18 decimal fixed point argument.\n     */\n    function _ln(int256 a) private pure returns (int256) {\n        unchecked {\n            if (a < ONE_18) {\n                // Since ln(a^k) = k * ln(a), we can compute ln(a) as ln(a) = ln((1/a)^(-1)) = - ln((1/a)). If a is less\n                // than one, 1/a will be greater than one, and this if statement will not be entered in the recursive call.\n                // Fixed point division requires multiplying by ONE_18.\n                return (-_ln((ONE_18 * ONE_18) / a));\n            }\n\n            // First, we use the fact that ln^(a * b) = ln(a) + ln(b) to decompose ln(a) into a sum of powers of two, which\n            // we call x_n, where x_n == 2^(7 - n), which are the natural logarithm of precomputed quantities a_n (that is,\n            // ln(a_n) = x_n). We choose the first x_n, x0, to equal 2^7 because the exponential of all larger powers cannot\n            // be represented as 18 fixed point decimal numbers in 256 bits, and are therefore larger than a.\n            // At the end of this process we will have the sum of all x_n = ln(a_n) that apply, and the remainder of this\n            // decomposition, which will be lower than the smallest a_n.\n            // ln(a) = k_0 * x_0 + k_1 * x_1 + ... + k_n * x_n + ln(remainder), where each k_n equals either 0 or 1.\n            // We mutate a by subtracting a_n, making it the remainder of the decomposition.\n\n            // For reasons related to how `exp` works, the first two a_n (e^(2^7) and e^(2^6)) are not stored as fixed point\n            // numbers with 18 decimals, but instead as plain integers with 0 decimals, so we need to multiply them by\n            // ONE_18 to convert them to fixed point.\n            // For each a_n, we test if that term is present in the decomposition (if a is larger than it), and if so divide\n            // by it and compute the accumulated sum.\n\n            int256 sum = 0;\n            if (a >= a0 * ONE_18) {\n                a /= a0; // Integer, not fixed point division\n                sum += x0;\n            }\n\n            if (a >= a1 * ONE_18) {\n                a /= a1; // Integer, not fixed point division\n                sum += x1;\n            }\n\n            // All other a_n and x_n are stored as 20 digit fixed point numbers, so we convert the sum and a to this format.\n            sum *= 100;\n            a *= 100;\n\n            // Because further a_n are  20 digit fixed point numbers, we multiply by ONE_20 when dividing by them.\n\n            if (a >= a2) {\n                a = (a * ONE_20) / a2;\n                sum += x2;\n            }\n\n            if (a >= a3) {\n                a = (a * ONE_20) / a3;\n                sum += x3;\n            }\n\n            if (a >= a4) {\n                a = (a * ONE_20) / a4;\n                sum += x4;\n            }\n\n            if (a >= a5) {\n                a = (a * ONE_20) / a5;\n                sum += x5;\n            }\n\n            if (a >= a6) {\n                a = (a * ONE_20) / a6;\n                sum += x6;\n            }\n\n            if (a >= a7) {\n                a = (a * ONE_20) / a7;\n                sum += x7;\n            }\n\n            if (a >= a8) {\n                a = (a * ONE_20) / a8;\n                sum += x8;\n            }\n\n            if (a >= a9) {\n                a = (a * ONE_20) / a9;\n                sum += x9;\n            }\n\n            if (a >= a10) {\n                a = (a * ONE_20) / a10;\n                sum += x10;\n            }\n\n            if (a >= a11) {\n                a = (a * ONE_20) / a11;\n                sum += x11;\n            }\n\n            // a is now a small number (smaller than a_11, which roughly equals 1.06). This means we can use a Taylor series\n            // that converges rapidly for values of `a` close to one - the same one used in ln_36.\n            // Let z = (a - 1) / (a + 1).\n            // ln(a) = 2 * (z + z^3 / 3 + z^5 / 5 + z^7 / 7 + ... + z^(2 * n + 1) / (2 * n + 1))\n\n            // Recall that 20 digit fixed point division requires multiplying by ONE_20, and multiplication requires\n            // division by ONE_20.\n            int256 z = ((a - ONE_20) * ONE_20) / (a + ONE_20);\n            int256 z_squared = (z * z) / ONE_20;\n\n            // num is the numerator of the series: the z^(2 * n + 1) term\n            int256 num = z;\n\n            // seriesSum holds the accumulated sum of each term in the series, starting with the initial z\n            int256 seriesSum = num;\n\n            // In each step, the numerator is multiplied by z^2\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 3;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 5;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 7;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 9;\n\n            num = (num * z_squared) / ONE_20;\n            seriesSum += num / 11;\n\n            // 6 Taylor terms are sufficient for 36 decimal precision.\n\n            // Finally, we multiply by 2 (non fixed point) to compute ln(remainder)\n            seriesSum *= 2;\n\n            // We now have the sum of all x_n present, and the Taylor approximation of the logarithm of the remainder (both\n            // with 20 decimals). All that remains is to sum these two, and then drop two digits to return a 18 decimal\n            // value.\n\n            return (sum + seriesSum) / 100;\n        }\n    }\n\n    /**\n     * @dev Intrnal high precision (36 decimal places) natural logarithm (ln(x)) with signed 18 decimal fixed point argument,\n     * for x close to one.\n     *\n     * Should only be used if x is between LN_36_LOWER_BOUND and LN_36_UPPER_BOUND.\n     */\n    function _ln_36(int256 x) private pure returns (int256) {\n        unchecked {\n            // Since ln(1) = 0, a value of x close to one will yield a very small result, which makes using 36 digits\n            // worthwhile.\n\n            // First, we transform x to a 36 digit fixed point value.\n            x *= ONE_18;\n\n            // We will use the following Taylor expansion, which converges very rapidly. Let z = (x - 1) / (x + 1).\n            // ln(x) = 2 * (z + z^3 / 3 + z^5 / 5 + z^7 / 7 + ... + z^(2 * n + 1) / (2 * n + 1))\n\n            // Recall that 36 digit fixed point division requires multiplying by ONE_36, and multiplication requires\n            // division by ONE_36.\n            int256 z = ((x - ONE_36) * ONE_36) / (x + ONE_36);\n            int256 z_squared = (z * z) / ONE_36;\n\n            // num is the numerator of the series: the z^(2 * n + 1) term\n            int256 num = z;\n\n            // seriesSum holds the accumulated sum of each term in the series, starting with the initial z\n            int256 seriesSum = num;\n\n            // In each step, the numerator is multiplied by z^2\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 3;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 5;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 7;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 9;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 11;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 13;\n\n            num = (num * z_squared) / ONE_36;\n            seriesSum += num / 15;\n\n            // 8 Taylor terms are sufficient for 36 decimal precision.\n\n            // All that remains is multiplying by 2 (non fixed point).\n            return seriesSum * 2;\n        }\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/math/PMath.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\npragma solidity ^0.8.0;\n\n/* solhint-disable private-vars-leading-underscore, reason-string */\n\nlibrary PMath {\n    uint256 internal constant ONE = 1e18; // 18 decimal places\n    int256 internal constant IONE = 1e18; // 18 decimal places\n\n    function subMax0(uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            return (a >= b ? a - b : 0);\n        }\n    }\n\n    function subNoNeg(int256 a, int256 b) internal pure returns (int256) {\n        require(a >= b, \"negative\");\n        return a - b; // no unchecked since if b is very negative, a - b might overflow\n    }\n\n    function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 product = a * b;\n        unchecked {\n            return product / ONE;\n        }\n    }\n\n    function mulDown(int256 a, int256 b) internal pure returns (int256) {\n        int256 product = a * b;\n        unchecked {\n            return product / IONE;\n        }\n    }\n\n    function divDown(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 aInflated = a * ONE;\n        unchecked {\n            return aInflated / b;\n        }\n    }\n\n    function divDown(int256 a, int256 b) internal pure returns (int256) {\n        int256 aInflated = a * IONE;\n        unchecked {\n            return aInflated / b;\n        }\n    }\n\n    function rawDivUp(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a + b - 1) / b;\n    }\n\n    // @author Uniswap\n    function sqrt(uint256 y) internal pure returns (uint256 z) {\n        if (y > 3) {\n            z = y;\n            uint256 x = y / 2 + 1;\n            while (x < z) {\n                z = x;\n                x = (y / x + x) / 2;\n            }\n        } else if (y != 0) {\n            z = 1;\n        }\n    }\n\n    function square(uint256 x) internal pure returns (uint256) {\n        return x * x;\n    }\n\n    function squareDown(uint256 x) internal pure returns (uint256) {\n        return mulDown(x, x);\n    }\n\n    function abs(int256 x) internal pure returns (uint256) {\n        return uint256(x > 0 ? x : -x);\n    }\n\n    function neg(int256 x) internal pure returns (int256) {\n        return x * (-1);\n    }\n\n    function neg(uint256 x) internal pure returns (int256) {\n        return Int(x) * (-1);\n    }\n\n    function max(uint256 x, uint256 y) internal pure returns (uint256) {\n        return (x > y ? x : y);\n    }\n\n    function max(int256 x, int256 y) internal pure returns (int256) {\n        return (x > y ? x : y);\n    }\n\n    function min(uint256 x, uint256 y) internal pure returns (uint256) {\n        return (x < y ? x : y);\n    }\n\n    function min(int256 x, int256 y) internal pure returns (int256) {\n        return (x < y ? x : y);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                               SIGNED CASTS\n    //////////////////////////////////////////////////////////////*/\n\n    function Int(uint256 x) internal pure returns (int256) {\n        require(x <= uint256(type(int256).max));\n        return int256(x);\n    }\n\n    function Int128(int256 x) internal pure returns (int128) {\n        require(type(int128).min <= x && x <= type(int128).max);\n        return int128(x);\n    }\n\n    function Int128(uint256 x) internal pure returns (int128) {\n        return Int128(Int(x));\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                               UNSIGNED CASTS\n    //////////////////////////////////////////////////////////////*/\n\n    function Uint(int256 x) internal pure returns (uint256) {\n        require(x >= 0);\n        return uint256(x);\n    }\n\n    function Uint32(uint256 x) internal pure returns (uint32) {\n        require(x <= type(uint32).max);\n        return uint32(x);\n    }\n\n    function Uint64(uint256 x) internal pure returns (uint64) {\n        require(x <= type(uint64).max);\n        return uint64(x);\n    }\n\n    function Uint112(uint256 x) internal pure returns (uint112) {\n        require(x <= type(uint112).max);\n        return uint112(x);\n    }\n\n    function Uint96(uint256 x) internal pure returns (uint96) {\n        require(x <= type(uint96).max);\n        return uint96(x);\n    }\n\n    function Uint128(uint256 x) internal pure returns (uint128) {\n        require(x <= type(uint128).max);\n        return uint128(x);\n    }\n\n    function Uint192(uint256 x) internal pure returns (uint192) {\n        require(x <= type(uint192).max);\n        return uint192(x);\n    }\n\n    function isAApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) {\n        return mulDown(b, ONE - eps) <= a && a <= mulDown(b, ONE + eps);\n    }\n\n    function isAGreaterApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) {\n        return a >= b && a <= mulDown(b, ONE + eps);\n    }\n\n    function isASmallerApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) {\n        return a <= b && a >= mulDown(b, ONE - eps);\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/MiniHelpers.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nlibrary MiniHelpers {\n    function isCurrentlyExpired(uint256 expiry) internal view returns (bool) {\n        return (expiry <= block.timestamp);\n    }\n\n    function isExpired(uint256 expiry, uint256 blockTime) internal pure returns (bool) {\n        return (expiry <= blockTime);\n    }\n\n    function isTimeInThePast(uint256 timestamp) internal view returns (bool) {\n        return (timestamp <= block.timestamp); // same definition as isCurrentlyExpired\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/libraries/TokenHelper.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"../../interfaces/IWETH.sol\";\n\nabstract contract TokenHelper {\n    using SafeERC20 for IERC20;\n\n    address internal constant NATIVE = address(0);\n    uint256 internal constant LOWER_BOUND_APPROVAL = type(uint96).max / 2; // some tokens use 96 bits for approval\n\n    function _transferIn(address token, address from, uint256 amount) internal {\n        if (token == NATIVE) require(msg.value == amount, \"eth mismatch\");\n        else if (amount != 0) IERC20(token).safeTransferFrom(from, address(this), amount);\n    }\n\n    function _transferFrom(IERC20 token, address from, address to, uint256 amount) internal {\n        if (amount != 0) token.safeTransferFrom(from, to, amount);\n    }\n\n    function _transferOut(address token, address to, uint256 amount) internal {\n        if (amount == 0) return;\n        if (token == NATIVE) {\n            (bool success, ) = to.call{value: amount}(\"\");\n            require(success, \"eth send failed\");\n        } else {\n            IERC20(token).safeTransfer(to, amount);\n        }\n    }\n\n    function _transferOut(address[] memory tokens, address to, uint256[] memory amounts) internal {\n        uint256 numTokens = tokens.length;\n        require(numTokens == amounts.length, \"length mismatch\");\n        for (uint256 i = 0; i < numTokens; ) {\n            _transferOut(tokens[i], to, amounts[i]);\n            unchecked {\n                i++;\n            }\n        }\n    }\n\n    function _selfBalance(address token) internal view returns (uint256) {\n        return (token == NATIVE) ? address(this).balance : IERC20(token).balanceOf(address(this));\n    }\n\n    function _selfBalance(IERC20 token) internal view returns (uint256) {\n        return token.balanceOf(address(this));\n    }\n\n    /// @notice Approves the stipulated contract to spend the given allowance in the given token\n    /// @dev PLS PAY ATTENTION to tokens that requires the approval to be set to 0 before changing it\n    function _safeApprove(address token, address to, uint256 value) internal {\n        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));\n        require(success && (data.length == 0 || abi.decode(data, (bool))), \"Safe Approve\");\n    }\n\n    function _safeApproveInf(address token, address to) internal {\n        if (token == NATIVE) return;\n        if (IERC20(token).allowance(address(this), to) < LOWER_BOUND_APPROVAL) {\n            _safeApprove(token, to, 0);\n            _safeApprove(token, to, type(uint256).max);\n        }\n    }\n\n    function _wrap_unwrap_ETH(address tokenIn, address tokenOut, uint256 netTokenIn) internal {\n        if (tokenIn == NATIVE) IWETH(tokenOut).deposit{value: netTokenIn}();\n        else IWETH(tokenIn).withdraw(netTokenIn);\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/Market/MarketMathCore.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"../libraries/math/PMath.sol\";\nimport \"../libraries/math/LogExpMath.sol\";\n\nimport \"../StandardizedYield/PYIndex.sol\";\nimport \"../libraries/MiniHelpers.sol\";\nimport \"../libraries/Errors.sol\";\n\nstruct MarketState {\n    int256 totalPt;\n    int256 totalSy;\n    int256 totalLp;\n    address treasury;\n    /// immutable variables ///\n    int256 scalarRoot;\n    uint256 expiry;\n    /// fee data ///\n    uint256 lnFeeRateRoot;\n    uint256 reserveFeePercent; // base 100\n    /// last trade data ///\n    uint256 lastLnImpliedRate;\n}\n\n// params that are expensive to compute, therefore we pre-compute them\nstruct MarketPreCompute {\n    int256 rateScalar;\n    int256 totalAsset;\n    int256 rateAnchor;\n    int256 feeRate;\n}\n\n// solhint-disable ordering\nlibrary MarketMathCore {\n    using PMath for uint256;\n    using PMath for int256;\n    using LogExpMath for int256;\n    using PYIndexLib for PYIndex;\n\n    int256 internal constant MINIMUM_LIQUIDITY = 10 ** 3;\n    int256 internal constant PERCENTAGE_DECIMALS = 100;\n    uint256 internal constant DAY = 86400;\n    uint256 internal constant IMPLIED_RATE_TIME = 365 * DAY;\n\n    int256 internal constant MAX_MARKET_PROPORTION = (1e18 * 96) / 100;\n\n    using PMath for uint256;\n    using PMath for int256;\n\n    /*///////////////////////////////////////////////////////////////\n                UINT FUNCTIONS TO PROXY TO CORE FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function addLiquidity(\n        MarketState memory market,\n        uint256 syDesired,\n        uint256 ptDesired,\n        uint256 blockTime\n    ) internal pure returns (uint256 lpToReserve, uint256 lpToAccount, uint256 syUsed, uint256 ptUsed) {\n        (int256 _lpToReserve, int256 _lpToAccount, int256 _syUsed, int256 _ptUsed) = addLiquidityCore(\n            market,\n            syDesired.Int(),\n            ptDesired.Int(),\n            blockTime\n        );\n\n        lpToReserve = _lpToReserve.Uint();\n        lpToAccount = _lpToAccount.Uint();\n        syUsed = _syUsed.Uint();\n        ptUsed = _ptUsed.Uint();\n    }\n\n    function removeLiquidity(\n        MarketState memory market,\n        uint256 lpToRemove\n    ) internal pure returns (uint256 netSyToAccount, uint256 netPtToAccount) {\n        (int256 _syToAccount, int256 _ptToAccount) = removeLiquidityCore(market, lpToRemove.Int());\n\n        netSyToAccount = _syToAccount.Uint();\n        netPtToAccount = _ptToAccount.Uint();\n    }\n\n    function swapExactPtForSy(\n        MarketState memory market,\n        PYIndex index,\n        uint256 exactPtToMarket,\n        uint256 blockTime\n    ) internal pure returns (uint256 netSyToAccount, uint256 netSyFee, uint256 netSyToReserve) {\n        (int256 _netSyToAccount, int256 _netSyFee, int256 _netSyToReserve) = executeTradeCore(\n            market,\n            index,\n            exactPtToMarket.neg(),\n            blockTime\n        );\n\n        netSyToAccount = _netSyToAccount.Uint();\n        netSyFee = _netSyFee.Uint();\n        netSyToReserve = _netSyToReserve.Uint();\n    }\n\n    function swapSyForExactPt(\n        MarketState memory market,\n        PYIndex index,\n        uint256 exactPtToAccount,\n        uint256 blockTime\n    ) internal pure returns (uint256 netSyToMarket, uint256 netSyFee, uint256 netSyToReserve) {\n        (int256 _netSyToAccount, int256 _netSyFee, int256 _netSyToReserve) = executeTradeCore(\n            market,\n            index,\n            exactPtToAccount.Int(),\n            blockTime\n        );\n\n        netSyToMarket = _netSyToAccount.neg().Uint();\n        netSyFee = _netSyFee.Uint();\n        netSyToReserve = _netSyToReserve.Uint();\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                    CORE FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function addLiquidityCore(\n        MarketState memory market,\n        int256 syDesired,\n        int256 ptDesired,\n        uint256 blockTime\n    ) internal pure returns (int256 lpToReserve, int256 lpToAccount, int256 syUsed, int256 ptUsed) {\n        /// ------------------------------------------------------------\n        /// CHECKS\n        /// ------------------------------------------------------------\n        if (syDesired == 0 || ptDesired == 0) revert Errors.MarketZeroAmountsInput();\n        if (MiniHelpers.isExpired(market.expiry, blockTime)) revert Errors.MarketExpired();\n\n        /// ------------------------------------------------------------\n        /// MATH\n        /// ------------------------------------------------------------\n        if (market.totalLp == 0) {\n            lpToAccount = PMath.sqrt((syDesired * ptDesired).Uint()).Int() - MINIMUM_LIQUIDITY;\n            lpToReserve = MINIMUM_LIQUIDITY;\n            syUsed = syDesired;\n            ptUsed = ptDesired;\n        } else {\n            int256 netLpByPt = (ptDesired * market.totalLp) / market.totalPt;\n            int256 netLpBySy = (syDesired * market.totalLp) / market.totalSy;\n            if (netLpByPt < netLpBySy) {\n                lpToAccount = netLpByPt;\n                ptUsed = ptDesired;\n                syUsed = (market.totalSy * lpToAccount) / market.totalLp;\n            } else {\n                lpToAccount = netLpBySy;\n                syUsed = syDesired;\n                ptUsed = (market.totalPt * lpToAccount) / market.totalLp;\n            }\n        }\n\n        if (lpToAccount <= 0) revert Errors.MarketZeroAmountsOutput();\n\n        /// ------------------------------------------------------------\n        /// WRITE\n        /// ------------------------------------------------------------\n        market.totalSy += syUsed;\n        market.totalPt += ptUsed;\n        market.totalLp += lpToAccount + lpToReserve;\n    }\n\n    function removeLiquidityCore(\n        MarketState memory market,\n        int256 lpToRemove\n    ) internal pure returns (int256 netSyToAccount, int256 netPtToAccount) {\n        /// ------------------------------------------------------------\n        /// CHECKS\n        /// ------------------------------------------------------------\n        if (lpToRemove == 0) revert Errors.MarketZeroAmountsInput();\n\n        /// ------------------------------------------------------------\n        /// MATH\n        /// ------------------------------------------------------------\n        netSyToAccount = (lpToRemove * market.totalSy) / market.totalLp;\n        netPtToAccount = (lpToRemove * market.totalPt) / market.totalLp;\n\n        if (netSyToAccount == 0 && netPtToAccount == 0) revert Errors.MarketZeroAmountsOutput();\n\n        /// ------------------------------------------------------------\n        /// WRITE\n        /// ------------------------------------------------------------\n        market.totalLp = market.totalLp.subNoNeg(lpToRemove);\n        market.totalPt = market.totalPt.subNoNeg(netPtToAccount);\n        market.totalSy = market.totalSy.subNoNeg(netSyToAccount);\n    }\n\n    function executeTradeCore(\n        MarketState memory market,\n        PYIndex index,\n        int256 netPtToAccount,\n        uint256 blockTime\n    ) internal pure returns (int256 netSyToAccount, int256 netSyFee, int256 netSyToReserve) {\n        /// ------------------------------------------------------------\n        /// CHECKS\n        /// ------------------------------------------------------------\n        if (MiniHelpers.isExpired(market.expiry, blockTime)) revert Errors.MarketExpired();\n        if (market.totalPt <= netPtToAccount)\n            revert Errors.MarketInsufficientPtForTrade(market.totalPt, netPtToAccount);\n\n        /// ------------------------------------------------------------\n        /// MATH\n        /// ------------------------------------------------------------\n        MarketPreCompute memory comp = getMarketPreCompute(market, index, blockTime);\n\n        (netSyToAccount, netSyFee, netSyToReserve) = calcTrade(market, comp, index, netPtToAccount);\n\n        /// ------------------------------------------------------------\n        /// WRITE\n        /// ------------------------------------------------------------\n        _setNewMarketStateTrade(market, comp, index, netPtToAccount, netSyToAccount, netSyToReserve, blockTime);\n    }\n\n    function getMarketPreCompute(\n        MarketState memory market,\n        PYIndex index,\n        uint256 blockTime\n    ) internal pure returns (MarketPreCompute memory res) {\n        if (MiniHelpers.isExpired(market.expiry, blockTime)) revert Errors.MarketExpired();\n\n        uint256 timeToExpiry = market.expiry - blockTime;\n\n        res.rateScalar = _getRateScalar(market, timeToExpiry);\n        res.totalAsset = index.syToAsset(market.totalSy);\n\n        if (market.totalPt == 0 || res.totalAsset == 0)\n            revert Errors.MarketZeroTotalPtOrTotalAsset(market.totalPt, res.totalAsset);\n\n        res.rateAnchor = _getRateAnchor(\n            market.totalPt,\n            market.lastLnImpliedRate,\n            res.totalAsset,\n            res.rateScalar,\n            timeToExpiry\n        );\n        res.feeRate = _getExchangeRateFromImpliedRate(market.lnFeeRateRoot, timeToExpiry);\n    }\n\n    function calcTrade(\n        MarketState memory market,\n        MarketPreCompute memory comp,\n        PYIndex index,\n        int256 netPtToAccount\n    ) internal pure returns (int256 netSyToAccount, int256 netSyFee, int256 netSyToReserve) {\n        int256 preFeeExchangeRate = _getExchangeRate(\n            market.totalPt,\n            comp.totalAsset,\n            comp.rateScalar,\n            comp.rateAnchor,\n            netPtToAccount\n        );\n\n        int256 preFeeAssetToAccount = netPtToAccount.divDown(preFeeExchangeRate).neg();\n        int256 fee = comp.feeRate;\n\n        if (netPtToAccount > 0) {\n            int256 postFeeExchangeRate = preFeeExchangeRate.divDown(fee);\n            if (postFeeExchangeRate < PMath.IONE) revert Errors.MarketExchangeRateBelowOne(postFeeExchangeRate);\n\n            fee = preFeeAssetToAccount.mulDown(PMath.IONE - fee);\n        } else {\n            fee = ((preFeeAssetToAccount * (PMath.IONE - fee)) / fee).neg();\n        }\n\n        int256 netAssetToReserve = (fee * market.reserveFeePercent.Int()) / PERCENTAGE_DECIMALS;\n        int256 netAssetToAccount = preFeeAssetToAccount - fee;\n\n        netSyToAccount = netAssetToAccount < 0\n            ? index.assetToSyUp(netAssetToAccount)\n            : index.assetToSy(netAssetToAccount);\n        netSyFee = index.assetToSy(fee);\n        netSyToReserve = index.assetToSy(netAssetToReserve);\n    }\n\n    function _setNewMarketStateTrade(\n        MarketState memory market,\n        MarketPreCompute memory comp,\n        PYIndex index,\n        int256 netPtToAccount,\n        int256 netSyToAccount,\n        int256 netSyToReserve,\n        uint256 blockTime\n    ) internal pure {\n        uint256 timeToExpiry = market.expiry - blockTime;\n\n        market.totalPt = market.totalPt.subNoNeg(netPtToAccount);\n        market.totalSy = market.totalSy.subNoNeg(netSyToAccount + netSyToReserve);\n\n        market.lastLnImpliedRate = _getLnImpliedRate(\n            market.totalPt,\n            index.syToAsset(market.totalSy),\n            comp.rateScalar,\n            comp.rateAnchor,\n            timeToExpiry\n        );\n\n        if (market.lastLnImpliedRate == 0) revert Errors.MarketZeroLnImpliedRate();\n    }\n\n    function _getRateAnchor(\n        int256 totalPt,\n        uint256 lastLnImpliedRate,\n        int256 totalAsset,\n        int256 rateScalar,\n        uint256 timeToExpiry\n    ) internal pure returns (int256 rateAnchor) {\n        int256 newExchangeRate = _getExchangeRateFromImpliedRate(lastLnImpliedRate, timeToExpiry);\n\n        if (newExchangeRate < PMath.IONE) revert Errors.MarketExchangeRateBelowOne(newExchangeRate);\n\n        {\n            int256 proportion = totalPt.divDown(totalPt + totalAsset);\n\n            int256 lnProportion = _logProportion(proportion);\n\n            rateAnchor = newExchangeRate - lnProportion.divDown(rateScalar);\n        }\n    }\n\n    /// @notice Calculates the current market implied rate.\n    /// @return lnImpliedRate the implied rate\n    function _getLnImpliedRate(\n        int256 totalPt,\n        int256 totalAsset,\n        int256 rateScalar,\n        int256 rateAnchor,\n        uint256 timeToExpiry\n    ) internal pure returns (uint256 lnImpliedRate) {\n        // This will check for exchange rates < PMath.IONE\n        int256 exchangeRate = _getExchangeRate(totalPt, totalAsset, rateScalar, rateAnchor, 0);\n\n        // exchangeRate >= 1 so its ln >= 0\n        uint256 lnRate = exchangeRate.ln().Uint();\n\n        lnImpliedRate = (lnRate * IMPLIED_RATE_TIME) / timeToExpiry;\n    }\n\n    /// @notice Converts an implied rate to an exchange rate given a time to expiry. The\n    /// formula is E = e^rt\n    function _getExchangeRateFromImpliedRate(\n        uint256 lnImpliedRate,\n        uint256 timeToExpiry\n    ) internal pure returns (int256 exchangeRate) {\n        uint256 rt = (lnImpliedRate * timeToExpiry) / IMPLIED_RATE_TIME;\n\n        exchangeRate = LogExpMath.exp(rt.Int());\n    }\n\n    function _getExchangeRate(\n        int256 totalPt,\n        int256 totalAsset,\n        int256 rateScalar,\n        int256 rateAnchor,\n        int256 netPtToAccount\n    ) internal pure returns (int256 exchangeRate) {\n        int256 numerator = totalPt.subNoNeg(netPtToAccount);\n\n        int256 proportion = (numerator.divDown(totalPt + totalAsset));\n\n        if (proportion > MAX_MARKET_PROPORTION)\n            revert Errors.MarketProportionTooHigh(proportion, MAX_MARKET_PROPORTION);\n\n        int256 lnProportion = _logProportion(proportion);\n\n        exchangeRate = lnProportion.divDown(rateScalar) + rateAnchor;\n\n        if (exchangeRate < PMath.IONE) revert Errors.MarketExchangeRateBelowOne(exchangeRate);\n    }\n\n    function _logProportion(int256 proportion) internal pure returns (int256 res) {\n        if (proportion == PMath.IONE) revert Errors.MarketProportionMustNotEqualOne();\n\n        int256 logitP = proportion.divDown(PMath.IONE - proportion);\n\n        res = logitP.ln();\n    }\n\n    function _getRateScalar(MarketState memory market, uint256 timeToExpiry) internal pure returns (int256 rateScalar) {\n        rateScalar = (market.scalarRoot * IMPLIED_RATE_TIME.Int()) / timeToExpiry.Int();\n        if (rateScalar <= 0) revert Errors.MarketRateScalarBelowZero(rateScalar);\n    }\n\n    function setInitialLnImpliedRate(\n        MarketState memory market,\n        PYIndex index,\n        int256 initialAnchor,\n        uint256 blockTime\n    ) internal pure {\n        /// ------------------------------------------------------------\n        /// CHECKS\n        /// ------------------------------------------------------------\n        if (MiniHelpers.isExpired(market.expiry, blockTime)) revert Errors.MarketExpired();\n\n        /// ------------------------------------------------------------\n        /// MATH\n        /// ------------------------------------------------------------\n        int256 totalAsset = index.syToAsset(market.totalSy);\n        uint256 timeToExpiry = market.expiry - blockTime;\n        int256 rateScalar = _getRateScalar(market, timeToExpiry);\n\n        /// ------------------------------------------------------------\n        /// WRITE\n        /// ------------------------------------------------------------\n        market.lastLnImpliedRate = _getLnImpliedRate(\n            market.totalPt,\n            totalAsset,\n            rateScalar,\n            initialAnchor,\n            timeToExpiry\n        );\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/Market/OracleLib.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"../libraries/Errors.sol\";\n\n/// Adapted from UniswapV3's Oracle\n\nlibrary OracleLib {\n    struct Observation {\n        uint32 blockTimestamp;\n        uint216 lnImpliedRateCumulative;\n        bool initialized;\n        // 1 SLOT = 256 bits\n    }\n\n    function transform(\n        Observation memory last,\n        uint32 blockTimestamp,\n        uint96 lnImpliedRate\n    ) public pure returns (Observation memory) {\n        return\n            Observation({\n                blockTimestamp: blockTimestamp,\n                lnImpliedRateCumulative: last.lnImpliedRateCumulative +\n                    uint216(lnImpliedRate) *\n                    (blockTimestamp - last.blockTimestamp),\n                initialized: true\n            });\n    }\n\n    function initialize(\n        Observation[65535] storage self,\n        uint32 time\n    ) public returns (uint16 cardinality, uint16 cardinalityNext) {\n        self[0] = Observation({blockTimestamp: time, lnImpliedRateCumulative: 0, initialized: true});\n        return (1, 1);\n    }\n\n    function write(\n        Observation[65535] storage self,\n        uint16 index,\n        uint32 blockTimestamp,\n        uint96 lnImpliedRate,\n        uint16 cardinality,\n        uint16 cardinalityNext\n    ) public returns (uint16 indexUpdated, uint16 cardinalityUpdated) {\n        Observation memory last = self[index];\n\n        // early return if we've already written an observation this block\n        if (last.blockTimestamp == blockTimestamp) return (index, cardinality);\n\n        // if the conditions are right, we can bump the cardinality\n        if (cardinalityNext > cardinality && index == (cardinality - 1)) {\n            cardinalityUpdated = cardinalityNext;\n        } else {\n            cardinalityUpdated = cardinality;\n        }\n\n        indexUpdated = (index + 1) % cardinalityUpdated;\n        self[indexUpdated] = transform(last, blockTimestamp, lnImpliedRate);\n    }\n\n    function grow(Observation[65535] storage self, uint16 current, uint16 next) public returns (uint16) {\n        if (current == 0) revert Errors.OracleUninitialized();\n        // no-op if the passed next value isn't greater than the current next value\n        if (next <= current) return current;\n        // store in each slot to prevent fresh SSTOREs in swaps\n        // this data will not be used because the initialized boolean is still false\n        for (uint16 i = current; i != next; ) {\n            self[i].blockTimestamp = 1;\n            unchecked {\n                ++i;\n            }\n        }\n        return next;\n    }\n\n    function binarySearch(\n        Observation[65535] storage self,\n        uint32 target,\n        uint16 index,\n        uint16 cardinality\n    ) public view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n        uint256 l = (index + 1) % cardinality; // oldest observation\n        uint256 r = l + cardinality - 1; // newest observation\n        uint256 i;\n        while (true) {\n            i = (l + r) / 2;\n\n            beforeOrAt = self[i % cardinality];\n\n            // we've landed on an uninitialized observation, keep searching higher (more recently)\n            if (!beforeOrAt.initialized) {\n                l = i + 1;\n                continue;\n            }\n\n            atOrAfter = self[(i + 1) % cardinality];\n\n            bool targetAtOrAfter = beforeOrAt.blockTimestamp <= target;\n\n            // check if we've found the answer!\n            if (targetAtOrAfter && target <= atOrAfter.blockTimestamp) break;\n\n            if (!targetAtOrAfter) r = i - 1;\n            else l = i + 1;\n        }\n    }\n\n    function getSurroundingObservations(\n        Observation[65535] storage self,\n        uint32 target,\n        uint96 lnImpliedRate,\n        uint16 index,\n        uint16 cardinality\n    ) public view returns (Observation memory beforeOrAt, Observation memory atOrAfter) {\n        // optimistically set before to the newest observation\n        beforeOrAt = self[index];\n\n        // if the target is chronologically at or after the newest observation, we can early return\n        if (beforeOrAt.blockTimestamp <= target) {\n            if (beforeOrAt.blockTimestamp == target) {\n                // if newest observation equals target, we're in the same block, so we can ignore atOrAfter\n                return (beforeOrAt, atOrAfter);\n            } else {\n                // otherwise, we need to transform\n                return (beforeOrAt, transform(beforeOrAt, target, lnImpliedRate));\n            }\n        }\n\n        // now, set beforeOrAt to the oldest observation\n        beforeOrAt = self[(index + 1) % cardinality];\n        if (!beforeOrAt.initialized) beforeOrAt = self[0];\n\n        // ensure that the target is chronologically at or after the oldest observation\n        if (target < beforeOrAt.blockTimestamp) revert Errors.OracleTargetTooOld(target, beforeOrAt.blockTimestamp);\n\n        // if we've reached this point, we have to binary search\n        return binarySearch(self, target, index, cardinality);\n    }\n\n    function observeSingle(\n        Observation[65535] storage self,\n        uint32 time,\n        uint32 secondsAgo,\n        uint96 lnImpliedRate,\n        uint16 index,\n        uint16 cardinality\n    ) public view returns (uint216 lnImpliedRateCumulative) {\n        if (secondsAgo == 0) {\n            Observation memory last = self[index];\n            if (last.blockTimestamp != time) {\n                return transform(last, time, lnImpliedRate).lnImpliedRateCumulative;\n            }\n            return last.lnImpliedRateCumulative;\n        }\n\n        uint32 target = time - secondsAgo;\n\n        (Observation memory beforeOrAt, Observation memory atOrAfter) = getSurroundingObservations(\n            self,\n            target,\n            lnImpliedRate,\n            index,\n            cardinality\n        );\n\n        if (target == beforeOrAt.blockTimestamp) {\n            // we're at the left boundary\n            return beforeOrAt.lnImpliedRateCumulative;\n        } else if (target == atOrAfter.blockTimestamp) {\n            // we're at the right boundary\n            return atOrAfter.lnImpliedRateCumulative;\n        } else {\n            // we're in the middle\n            return (beforeOrAt.lnImpliedRateCumulative +\n                uint216(\n                    (uint256(atOrAfter.lnImpliedRateCumulative - beforeOrAt.lnImpliedRateCumulative) *\n                        (target - beforeOrAt.blockTimestamp)) / (atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp)\n                ));\n        }\n    }\n\n    function observe(\n        Observation[65535] storage self,\n        uint32 time,\n        uint32[] memory secondsAgos,\n        uint96 lnImpliedRate,\n        uint16 index,\n        uint16 cardinality\n    ) public view returns (uint216[] memory lnImpliedRateCumulative) {\n        if (cardinality == 0) revert Errors.OracleZeroCardinality();\n\n        lnImpliedRateCumulative = new uint216[](secondsAgos.length);\n        for (uint256 i = 0; i < lnImpliedRateCumulative.length; ++i) {\n            lnImpliedRateCumulative[i] = observeSingle(self, time, secondsAgos[i], lnImpliedRate, index, cardinality);\n        }\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/Market/PendleGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IPGauge.sol\";\nimport \"../../interfaces/IPVeToken.sol\";\nimport \"../../interfaces/IPGaugeController.sol\";\nimport \"../../interfaces/IStandardizedYield.sol\";\n\nimport \"../RewardManager/RewardManager.sol\";\n\n/**\nInvariants to maintain:\n- before any changes to active balance, updateAndDistributeRewards() must be called\n */\nabstract contract PendleGauge is RewardManager, IPGauge {\n    using PMath for uint256;\n    using SafeERC20 for IERC20;\n    using ArrayLib for address[];\n\n    address private immutable SY;\n\n    uint256 internal constant TOKENLESS_PRODUCTION = 40;\n\n    address internal immutable PENDLE;\n    IPVeToken internal immutable vePENDLE;\n    address internal immutable gaugeController;\n\n    uint256 public totalActiveSupply;\n    mapping(address => uint256) public activeBalance;\n\n    constructor(address _SY, address _vePendle, address _gaugeController) {\n        SY = _SY;\n        vePENDLE = IPVeToken(_vePendle);\n        gaugeController = _gaugeController;\n        PENDLE = IPGaugeController(gaugeController).pendle();\n    }\n\n    /**\n     * @dev Since rewardShares is based on activeBalance, user's activeBalance must be updated AFTER\n        rewards is updated\n     * @dev It's intended to have user's activeBalance updated when rewards is redeemed\n     */\n    function _redeemRewards(address user) internal virtual returns (uint256[] memory rewardsOut) {\n        _updateAndDistributeRewards(user);\n        _updateUserActiveBalance(user);\n        rewardsOut = _doTransferOutRewards(user, user);\n        emit RedeemRewards(user, rewardsOut);\n    }\n\n    function _updateUserActiveBalance(address user) internal virtual {\n        _updateUserActiveBalanceForTwo(user, address(0));\n    }\n\n    function _updateUserActiveBalanceForTwo(address user1, address user2) internal virtual {\n        if (user1 != address(0) && user1 != address(this)) _updateUserActiveBalancePrivate(user1);\n        if (user2 != address(0) && user2 != address(this)) _updateUserActiveBalancePrivate(user2);\n    }\n\n    /**\n     * @dev should only be callable from `_updateUserActiveBalanceForTwo` to guarantee user != address(0) && user != address(this)\n     */\n    function _updateUserActiveBalancePrivate(address user) private {\n        assert(user != address(0) && user != address(this));\n\n        uint256 lpBalance = _stakedBalance(user);\n        uint256 veBoostedLpBalance = _calcVeBoostedLpBalance(user, lpBalance);\n\n        uint256 newActiveBalance = PMath.min(veBoostedLpBalance, lpBalance);\n\n        totalActiveSupply = totalActiveSupply - activeBalance[user] + newActiveBalance;\n        activeBalance[user] = newActiveBalance;\n    }\n\n    function _calcVeBoostedLpBalance(address user, uint256 lpBalance) internal virtual returns (uint256) {\n        (uint256 vePendleSupply, uint256 vePendleBalance) = vePENDLE.totalSupplyAndBalanceCurrent(user);\n        // Inspired by Curve's Gauge\n        uint256 veBoostedLpBalance = (lpBalance * TOKENLESS_PRODUCTION) / 100;\n        if (vePendleSupply > 0) {\n            veBoostedLpBalance +=\n                (((_totalStaked() * vePendleBalance) / vePendleSupply) * (100 - TOKENLESS_PRODUCTION)) /\n                100;\n        }\n        return veBoostedLpBalance;\n    }\n\n    function _redeemExternalReward() internal virtual override {\n        IStandardizedYield(SY).claimRewards(address(this));\n        IPGaugeController(gaugeController).redeemMarketReward();\n    }\n\n    function _stakedBalance(address user) internal view virtual returns (uint256);\n\n    function _totalStaked() internal view virtual returns (uint256);\n\n    function _rewardSharesTotal() internal view virtual override returns (uint256) {\n        return totalActiveSupply;\n    }\n\n    function _rewardSharesUser(address user) internal view virtual override returns (uint256) {\n        return activeBalance[user];\n    }\n\n    function _getRewardTokens() internal view virtual override returns (address[] memory) {\n        address[] memory SYRewards = IStandardizedYield(SY).getRewardTokens();\n        if (SYRewards.contains(PENDLE)) return SYRewards;\n        return SYRewards.append(PENDLE);\n    }\n\n    function _beforeTokenTransfer(address from, address to, uint256) internal virtual {\n        _updateAndDistributeRewardsForTwo(from, to);\n    }\n\n    function _afterTokenTransfer(address from, address to, uint256) internal virtual {\n        _updateUserActiveBalanceForTwo(from, to);\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/Market/v3/PendleMarketV3.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.17;\n\nimport \"../../../interfaces/IPMarketV3.sol\";\nimport \"../../../interfaces/IPMarketFactoryV3.sol\";\nimport \"../../../interfaces/IPMarketSwapCallback.sol\";\n\nimport \"../../erc20/PendleERC20Permit.sol\";\nimport \"../PendleGauge.sol\";\nimport \"../OracleLib.sol\";\n\n/**\nInvariance to maintain:\n- Internal balances totalPt & totalSy not interfered by people transferring tokens in directly\n- address(0) & address(this) should never have any rewards & activeBalance accounting done. This is\n    guaranteed by address(0) & address(this) check in each updateForTwo function\n*/\ncontract PendleMarketV3 is PendleERC20Permit, PendleGauge, IPMarketV3 {\n    using PMath for uint256;\n    using PMath for int256;\n    using MarketMathCore for MarketState;\n    using SafeERC20 for IERC20;\n    using PYIndexLib for IPYieldToken;\n    using OracleLib for OracleLib.Observation[65535];\n\n    struct MarketStorage {\n        int128 totalPt;\n        int128 totalSy;\n        // 1 SLOT = 256 bits\n        uint96 lastLnImpliedRate;\n        uint16 observationIndex;\n        uint16 observationCardinality;\n        uint16 observationCardinalityNext;\n        // 1 SLOT = 144 bits\n    }\n\n    string private constant NAME = \"Pendle Market\";\n    string private constant SYMBOL = \"PENDLE-LPT\";\n\n    IPPrincipalToken internal immutable PT;\n    IStandardizedYield internal immutable SY;\n    IPYieldToken internal immutable YT;\n\n    address public immutable factory;\n    uint256 public immutable expiry;\n\n    int256 internal immutable scalarRoot;\n    int256 internal immutable initialAnchor;\n    uint80 internal immutable lnFeeRateRoot;\n\n    MarketStorage public _storage;\n\n    OracleLib.Observation[65535] public observations;\n\n    modifier notExpired() {\n        if (isExpired()) revert Errors.MarketExpired();\n        _;\n    }\n\n    constructor(\n        address _PT,\n        int256 _scalarRoot,\n        int256 _initialAnchor,\n        uint80 _lnFeeRateRoot,\n        address _vePendle,\n        address _gaugeController\n    ) PendleERC20Permit(NAME, SYMBOL, 18) PendleGauge(IPPrincipalToken(_PT).SY(), _vePendle, _gaugeController) {\n        PT = IPPrincipalToken(_PT);\n        SY = IStandardizedYield(PT.SY());\n        YT = IPYieldToken(PT.YT());\n\n        (_storage.observationCardinality, _storage.observationCardinalityNext) = observations.initialize(\n            uint32(block.timestamp)\n        );\n\n        if (_scalarRoot <= 0) revert Errors.MarketScalarRootBelowZero(_scalarRoot);\n\n        scalarRoot = _scalarRoot;\n        initialAnchor = _initialAnchor;\n        lnFeeRateRoot = _lnFeeRateRoot;\n        expiry = IPPrincipalToken(_PT).expiry();\n        factory = msg.sender;\n    }\n\n    /**\n     * @notice PendleMarket allows users to provide in PT & SY in exchange for LPs, which\n     * will grant LP holders more exchange fee over time\n     * @dev will mint as much LP as possible such that the corresponding SY and PT used do\n     * not exceed `netSyDesired` and `netPtDesired`, respectively\n     * @dev PT and SY should be transferred to this contract prior to calling\n     * @dev will revert if PT is expired\n     */\n    function mint(\n        address receiver,\n        uint256 netSyDesired,\n        uint256 netPtDesired\n    ) external nonReentrant notExpired returns (uint256 netLpOut, uint256 netSyUsed, uint256 netPtUsed) {\n        MarketState memory market = readState(msg.sender);\n        PYIndex index = YT.newIndex();\n\n        uint256 lpToReserve;\n\n        (lpToReserve, netLpOut, netSyUsed, netPtUsed) = market.addLiquidity(\n            netSyDesired,\n            netPtDesired,\n            block.timestamp\n        );\n\n        // initializing the market\n        if (lpToReserve != 0) {\n            market.setInitialLnImpliedRate(index, initialAnchor, block.timestamp);\n            _mint(address(1), lpToReserve);\n        }\n\n        _mint(receiver, netLpOut);\n\n        _writeState(market);\n\n        if (_selfBalance(SY) < market.totalSy.Uint())\n            revert Errors.MarketInsufficientSyReceived(_selfBalance(SY), market.totalSy.Uint());\n        if (_selfBalance(PT) < market.totalPt.Uint())\n            revert Errors.MarketInsufficientPtReceived(_selfBalance(PT), market.totalPt.Uint());\n\n        emit Mint(receiver, netLpOut, netSyUsed, netPtUsed);\n    }\n\n    /**\n     * @notice LP Holders can burn their LP to receive back SY & PT proportionally\n     * to their share of the market\n     */\n    function burn(\n        address receiverSy,\n        address receiverPt,\n        uint256 netLpToBurn\n    ) external nonReentrant returns (uint256 netSyOut, uint256 netPtOut) {\n        MarketState memory market = readState(msg.sender);\n\n        _burn(address(this), netLpToBurn);\n\n        (netSyOut, netPtOut) = market.removeLiquidity(netLpToBurn);\n\n        if (receiverSy != address(this)) IERC20(SY).safeTransfer(receiverSy, netSyOut);\n        if (receiverPt != address(this)) IERC20(PT).safeTransfer(receiverPt, netPtOut);\n\n        _writeState(market);\n\n        emit Burn(receiverSy, receiverPt, netLpToBurn, netSyOut, netPtOut);\n    }\n\n    /**\n     * @notice Pendle Market allows swaps between PT & SY it is holding. This function\n     * aims to swap an exact amount of PT to SY.\n     * @dev steps working of this contract\n       - The outcome amount of SY will be precomputed by MarketMathLib\n       - Release the calculated amount of SY to receiver\n       - Callback to msg.sender if data.length > 0\n       - Ensure exactPtIn amount of PT has been transferred to this address\n     * @dev will revert if PT is expired\n     * @param data bytes data to be sent in the callback (if any)\n     */\n    function swapExactPtForSy(\n        address receiver,\n        uint256 exactPtIn,\n        bytes calldata data\n    ) external nonReentrant notExpired returns (uint256 netSyOut, uint256 netSyFee) {\n        MarketState memory market = readState(msg.sender);\n\n        uint256 netSyToReserve;\n        (netSyOut, netSyFee, netSyToReserve) = market.swapExactPtForSy(YT.newIndex(), exactPtIn, block.timestamp);\n\n        if (receiver != address(this)) IERC20(SY).safeTransfer(receiver, netSyOut);\n        IERC20(SY).safeTransfer(market.treasury, netSyToReserve);\n\n        _writeState(market);\n\n        if (data.length > 0) {\n            IPMarketSwapCallback(msg.sender).swapCallback(exactPtIn.neg(), netSyOut.Int(), data);\n        }\n\n        if (_selfBalance(PT) < market.totalPt.Uint())\n            revert Errors.MarketInsufficientPtReceived(_selfBalance(PT), market.totalPt.Uint());\n\n        emit Swap(msg.sender, receiver, exactPtIn.neg(), netSyOut.Int(), netSyFee, netSyToReserve);\n    }\n\n    /**\n     * @notice Pendle Market allows swaps between PT & SY it is holding. This function\n     * aims to swap SY for an exact amount of PT.\n     * @dev steps working of this function\n       - The exact outcome amount of PT will be transferred to receiver\n       - Callback to msg.sender if data.length > 0\n       - Ensure the calculated required amount of SY is transferred to this address\n     * @dev will revert if PT is expired\n     * @param data bytes data to be sent in the callback (if any)\n     */\n    function swapSyForExactPt(\n        address receiver,\n        uint256 exactPtOut,\n        bytes calldata data\n    ) external nonReentrant notExpired returns (uint256 netSyIn, uint256 netSyFee) {\n        MarketState memory market = readState(msg.sender);\n\n        uint256 netSyToReserve;\n        (netSyIn, netSyFee, netSyToReserve) = market.swapSyForExactPt(YT.newIndex(), exactPtOut, block.timestamp);\n\n        if (receiver != address(this)) IERC20(PT).safeTransfer(receiver, exactPtOut);\n        IERC20(SY).safeTransfer(market.treasury, netSyToReserve);\n\n        _writeState(market);\n\n        if (data.length > 0) {\n            IPMarketSwapCallback(msg.sender).swapCallback(exactPtOut.Int(), netSyIn.neg(), data);\n        }\n\n        // have received enough SY\n        if (_selfBalance(SY) < market.totalSy.Uint())\n            revert Errors.MarketInsufficientSyReceived(_selfBalance(SY), market.totalSy.Uint());\n\n        emit Swap(msg.sender, receiver, exactPtOut.Int(), netSyIn.neg(), netSyFee, netSyToReserve);\n    }\n\n    /// @notice forces balances to match reserves\n    function skim() external nonReentrant {\n        MarketState memory market = readState(msg.sender);\n        uint256 excessPt = _selfBalance(PT) - market.totalPt.Uint();\n        uint256 excessSy = _selfBalance(SY) - market.totalSy.Uint();\n        if (excessPt != 0) IERC20(PT).safeTransfer(market.treasury, excessPt);\n        if (excessSy != 0) IERC20(SY).safeTransfer(market.treasury, excessSy);\n    }\n\n    /**\n     * @notice redeems the user's reward\n     * @return amount of reward token redeemed, in the same order as `getRewardTokens()`\n     */\n    function redeemRewards(address user) external nonReentrant returns (uint256[] memory) {\n        return _redeemRewards(user);\n    }\n\n    /// @notice returns the list of reward tokens\n    function getRewardTokens() external view returns (address[] memory) {\n        return _getRewardTokens();\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                                ORACLE\n    //////////////////////////////////////////////////////////////*/\n\n    function observe(uint32[] memory secondsAgos) external view returns (uint216[] memory lnImpliedRateCumulative) {\n        return\n            observations.observe(\n                uint32(block.timestamp),\n                secondsAgos,\n                _storage.lastLnImpliedRate,\n                _storage.observationIndex,\n                _storage.observationCardinality\n            );\n    }\n\n    function increaseObservationsCardinalityNext(uint16 cardinalityNext) external nonReentrant {\n        uint16 cardinalityNextOld = _storage.observationCardinalityNext;\n        uint16 cardinalityNextNew = observations.grow(cardinalityNextOld, cardinalityNext);\n        if (cardinalityNextOld != cardinalityNextNew) {\n            _storage.observationCardinalityNext = cardinalityNextNew;\n            emit IncreaseObservationCardinalityNext(cardinalityNextOld, cardinalityNextNew);\n        }\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                                READ/WRITE STATES\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice read the state of the market from storage into memory for gas-efficient manipulation\n     */\n    function readState(address router) public view returns (MarketState memory market) {\n        market.totalPt = _storage.totalPt;\n        market.totalSy = _storage.totalSy;\n        market.totalLp = totalSupply().Int();\n\n        uint80 overriddenFee;\n\n        (market.treasury, overriddenFee, market.reserveFeePercent) = IPMarketFactoryV3(factory).getMarketConfig(\n            address(this),\n            router\n        );\n\n        market.lnFeeRateRoot = overriddenFee == 0 ? lnFeeRateRoot : overriddenFee;\n        market.scalarRoot = scalarRoot;\n        market.expiry = expiry;\n\n        market.lastLnImpliedRate = _storage.lastLnImpliedRate;\n    }\n\n    /// @notice write back the state of the market from memory to storage\n    function _writeState(MarketState memory market) internal {\n        uint96 lastLnImpliedRate96 = market.lastLnImpliedRate.Uint96();\n        int128 totalPt128 = market.totalPt.Int128();\n        int128 totalSy128 = market.totalSy.Int128();\n\n        (uint16 observationIndex, uint16 observationCardinality) = observations.write(\n            _storage.observationIndex,\n            uint32(block.timestamp),\n            _storage.lastLnImpliedRate,\n            _storage.observationCardinality,\n            _storage.observationCardinalityNext\n        );\n\n        _storage.totalPt = totalPt128;\n        _storage.totalSy = totalSy128;\n        _storage.lastLnImpliedRate = lastLnImpliedRate96;\n        _storage.observationIndex = observationIndex;\n        _storage.observationCardinality = observationCardinality;\n\n        emit UpdateImpliedRate(block.timestamp, market.lastLnImpliedRate);\n    }\n\n    function getNonOverrideLnFeeRateRoot() external view returns (uint80) {\n        return lnFeeRateRoot;\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                            TRIVIAL FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function readTokens() external view returns (IStandardizedYield _SY, IPPrincipalToken _PT, IPYieldToken _YT) {\n        _SY = SY;\n        _PT = PT;\n        _YT = YT;\n    }\n\n    function isExpired() public view returns (bool) {\n        return MiniHelpers.isCurrentlyExpired(expiry);\n    }\n\n    /*///////////////////////////////////////////////////////////////\n                    PENDLE GAUGE - RELATED\n    //////////////////////////////////////////////////////////////*/\n\n    function _stakedBalance(address user) internal view override returns (uint256) {\n        return balanceOf(user);\n    }\n\n    function _totalStaked() internal view override returns (uint256) {\n        return totalSupply();\n    }\n\n    // solhint-disable-next-line ordering\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal override(PendleERC20, PendleGauge) {\n        PendleGauge._beforeTokenTransfer(from, to, amount);\n    }\n\n    // solhint-disable-next-line ordering\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal override(PendleERC20, PendleGauge) {\n        PendleGauge._afterTokenTransfer(from, to, amount);\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/RewardManager/RewardManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"./RewardManagerAbstract.sol\";\n\n/// NOTE: This RewardManager is used with SY & YTv2 & PendleMarket. For YTv1, it will use RewardManagerAbstract\n/// NOTE: RewardManager must not have duplicated rewardTokens\nabstract contract RewardManager is RewardManagerAbstract {\n    using PMath for uint256;\n    using ArrayLib for uint256[];\n\n    uint256 public lastRewardBlock;\n\n    mapping(address => RewardState) public rewardState;\n\n    function _updateRewardIndex()\n        internal\n        virtual\n        override\n        returns (address[] memory tokens, uint256[] memory indexes)\n    {\n        tokens = _getRewardTokens();\n        indexes = new uint256[](tokens.length);\n\n        if (tokens.length == 0) return (tokens, indexes);\n\n        if (lastRewardBlock != block.number) {\n            // if we have not yet update the index for this block\n            lastRewardBlock = block.number;\n\n            uint256 totalShares = _rewardSharesTotal();\n\n            _redeemExternalReward();\n\n            for (uint256 i = 0; i < tokens.length; ++i) {\n                address token = tokens[i];\n\n                // the entire token balance of the contract must be the rewards of the contract\n\n                RewardState memory _state = rewardState[token];\n                (uint256 lastBalance, uint256 index) = (_state.lastBalance, _state.index);\n\n                uint256 accrued = _selfBalance(tokens[i]) - lastBalance;\n\n                if (index == 0) index = INITIAL_REWARD_INDEX;\n                if (totalShares != 0) index += accrued.divDown(totalShares);\n\n                rewardState[token] = RewardState({\n                    index: index.Uint128(),\n                    lastBalance: (lastBalance + accrued).Uint128()\n                });\n                indexes[i] = index;\n            }\n        } else {\n            for (uint256 i = 0; i < tokens.length; i++) {\n                indexes[i] = rewardState[tokens[i]].index;\n            }\n        }\n    }\n\n    /// @dev this function doesn't need redeemExternal since redeemExternal is bundled in updateRewardIndex\n    /// @dev this function also has to update rewardState.lastBalance\n    function _doTransferOutRewards(\n        address user,\n        address receiver\n    ) internal virtual override returns (uint256[] memory rewardAmounts) {\n        address[] memory tokens = _getRewardTokens();\n        rewardAmounts = new uint256[](tokens.length);\n        for (uint256 i = 0; i < tokens.length; i++) {\n            rewardAmounts[i] = userReward[tokens[i]][user].accrued;\n            if (rewardAmounts[i] != 0) {\n                userReward[tokens[i]][user].accrued = 0;\n                rewardState[tokens[i]].lastBalance -= rewardAmounts[i].Uint128();\n                _transferOut(tokens[i], receiver, rewardAmounts[i]);\n            }\n        }\n    }\n\n    function _getRewardTokens() internal view virtual returns (address[] memory);\n\n    function _rewardSharesTotal() internal view virtual returns (uint256);\n}\n"
      },
      "contracts/pendle/contracts/core/RewardManager/RewardManagerAbstract.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/IRewardManager.sol\";\n\nimport \"../libraries/ArrayLib.sol\";\nimport \"../libraries/TokenHelper.sol\";\nimport \"../libraries/math/PMath.sol\";\n\nimport \"./RewardManagerAbstract.sol\";\n\n/// NOTE: RewardManager must not have duplicated rewardTokens\nabstract contract RewardManagerAbstract is IRewardManager, TokenHelper {\n    using PMath for uint256;\n\n    uint256 internal constant INITIAL_REWARD_INDEX = 1;\n\n    struct RewardState {\n        uint128 index;\n        uint128 lastBalance;\n    }\n\n    struct UserReward {\n        uint128 index;\n        uint128 accrued;\n    }\n\n    // [token] => [user] => (index,accrued)\n    mapping(address => mapping(address => UserReward)) public userReward;\n\n    function _updateAndDistributeRewards(address user) internal virtual {\n        _updateAndDistributeRewardsForTwo(user, address(0));\n    }\n\n    function _updateAndDistributeRewardsForTwo(address user1, address user2) internal virtual {\n        (address[] memory tokens, uint256[] memory indexes) = _updateRewardIndex();\n        if (tokens.length == 0) return;\n\n        if (user1 != address(0) && user1 != address(this)) _distributeRewardsPrivate(user1, tokens, indexes);\n        if (user2 != address(0) && user2 != address(this)) _distributeRewardsPrivate(user2, tokens, indexes);\n    }\n\n    // should only be callable from `_updateAndDistributeRewardsForTwo` to guarantee user != address(0) && user != address(this)\n    function _distributeRewardsPrivate(address user, address[] memory tokens, uint256[] memory indexes) private {\n        assert(user != address(0) && user != address(this));\n\n        uint256 userShares = _rewardSharesUser(user);\n\n        for (uint256 i = 0; i < tokens.length; ++i) {\n            address token = tokens[i];\n            uint256 index = indexes[i];\n            uint256 userIndex = userReward[token][user].index;\n\n            if (userIndex == 0) {\n                userIndex = INITIAL_REWARD_INDEX.Uint128();\n            }\n\n            if (userIndex == index) continue;\n\n            uint256 deltaIndex = index - userIndex;\n            uint256 rewardDelta = userShares.mulDown(deltaIndex);\n            uint256 rewardAccrued = userReward[token][user].accrued + rewardDelta;\n\n            userReward[token][user] = UserReward({index: index.Uint128(), accrued: rewardAccrued.Uint128()});\n        }\n    }\n\n    function _updateRewardIndex() internal virtual returns (address[] memory tokens, uint256[] memory indexes);\n\n    function _redeemExternalReward() internal virtual;\n\n    function _doTransferOutRewards(\n        address user,\n        address receiver\n    ) internal virtual returns (uint256[] memory rewardAmounts);\n\n    function _rewardSharesUser(address user) internal view virtual returns (uint256);\n}\n"
      },
      "contracts/pendle/contracts/core/StandardizedYield/PYIndex.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\nimport \"../../interfaces/IPYieldToken.sol\";\nimport \"../../interfaces/IPPrincipalToken.sol\";\n\nimport \"./SYUtils.sol\";\nimport \"../libraries/math/PMath.sol\";\n\ntype PYIndex is uint256;\n\nlibrary PYIndexLib {\n    using PMath for uint256;\n    using PMath for int256;\n\n    function newIndex(IPYieldToken YT) internal returns (PYIndex) {\n        return PYIndex.wrap(YT.pyIndexCurrent());\n    }\n\n    function syToAsset(PYIndex index, uint256 syAmount) internal pure returns (uint256) {\n        return SYUtils.syToAsset(PYIndex.unwrap(index), syAmount);\n    }\n\n    function assetToSy(PYIndex index, uint256 assetAmount) internal pure returns (uint256) {\n        return SYUtils.assetToSy(PYIndex.unwrap(index), assetAmount);\n    }\n\n    function assetToSyUp(PYIndex index, uint256 assetAmount) internal pure returns (uint256) {\n        return SYUtils.assetToSyUp(PYIndex.unwrap(index), assetAmount);\n    }\n\n    function syToAssetUp(PYIndex index, uint256 syAmount) internal pure returns (uint256) {\n        uint256 _index = PYIndex.unwrap(index);\n        return SYUtils.syToAssetUp(_index, syAmount);\n    }\n\n    function syToAsset(PYIndex index, int256 syAmount) internal pure returns (int256) {\n        int256 sign = syAmount < 0 ? int256(-1) : int256(1);\n        return sign * (SYUtils.syToAsset(PYIndex.unwrap(index), syAmount.abs())).Int();\n    }\n\n    function assetToSy(PYIndex index, int256 assetAmount) internal pure returns (int256) {\n        int256 sign = assetAmount < 0 ? int256(-1) : int256(1);\n        return sign * (SYUtils.assetToSy(PYIndex.unwrap(index), assetAmount.abs())).Int();\n    }\n\n    function assetToSyUp(PYIndex index, int256 assetAmount) internal pure returns (int256) {\n        int256 sign = assetAmount < 0 ? int256(-1) : int256(1);\n        return sign * (SYUtils.assetToSyUp(PYIndex.unwrap(index), assetAmount.abs())).Int();\n    }\n}\n"
      },
      "contracts/pendle/contracts/core/StandardizedYield/SYUtils.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nlibrary SYUtils {\n    uint256 internal constant ONE = 1e18;\n\n    function syToAsset(uint256 exchangeRate, uint256 syAmount) internal pure returns (uint256) {\n        return (syAmount * exchangeRate) / ONE;\n    }\n\n    function syToAssetUp(uint256 exchangeRate, uint256 syAmount) internal pure returns (uint256) {\n        return (syAmount * exchangeRate + ONE - 1) / ONE;\n    }\n\n    function assetToSy(uint256 exchangeRate, uint256 assetAmount) internal pure returns (uint256) {\n        return (assetAmount * ONE) / exchangeRate;\n    }\n\n    function assetToSyUp(uint256 exchangeRate, uint256 assetAmount) internal pure returns (uint256) {\n        return (assetAmount * ONE + exchangeRate - 1) / exchangeRate;\n    }\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPGauge.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IPGauge {\n    function totalActiveSupply() external view returns (uint256);\n\n    function activeBalance(address user) external view returns (uint256);\n\n    // only available for newer factories. please check the verified contracts\n    event RedeemRewards(address indexed user, uint256[] rewardsOut);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPGaugeController.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IPGaugeController {\n    event MarketClaimReward(address indexed market, uint256 amount);\n\n    event ReceiveVotingResults(uint128 indexed wTime, address[] markets, uint256[] pendleAmounts);\n\n    event UpdateMarketReward(address indexed market, uint256 pendlePerSec, uint256 incentiveEndsAt);\n\n    function fundPendle(uint256 amount) external;\n\n    function withdrawPendle(uint256 amount) external;\n\n    function pendle() external returns (address);\n\n    function redeemMarketReward() external;\n\n    function rewardData(address pool) external view returns (uint128 pendlePerSec, uint128, uint128, uint128);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPInterestManagerYT.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IPInterestManagerYT {\n    event CollectInterestFee(uint256 amountInterestFee);\n\n    function userInterest(address user) external view returns (uint128 lastPYIndex, uint128 accruedInterest);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPMarket.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"./IPPrincipalToken.sol\";\nimport \"./IPYieldToken.sol\";\nimport \"./IStandardizedYield.sol\";\nimport \"./IPGauge.sol\";\nimport \"../core/Market/MarketMathCore.sol\";\n\ninterface IPMarket is IERC20Metadata, IPGauge {\n    event Mint(address indexed receiver, uint256 netLpMinted, uint256 netSyUsed, uint256 netPtUsed);\n\n    event Burn(\n        address indexed receiverSy,\n        address indexed receiverPt,\n        uint256 netLpBurned,\n        uint256 netSyOut,\n        uint256 netPtOut\n    );\n\n    event Swap(\n        address indexed caller,\n        address indexed receiver,\n        int256 netPtOut,\n        int256 netSyOut,\n        uint256 netSyFee,\n        uint256 netSyToReserve\n    );\n\n    event UpdateImpliedRate(uint256 indexed timestamp, uint256 lnLastImpliedRate);\n\n    event IncreaseObservationCardinalityNext(\n        uint16 observationCardinalityNextOld,\n        uint16 observationCardinalityNextNew\n    );\n\n    function mint(\n        address receiver,\n        uint256 netSyDesired,\n        uint256 netPtDesired\n    ) external returns (uint256 netLpOut, uint256 netSyUsed, uint256 netPtUsed);\n\n    function burn(\n        address receiverSy,\n        address receiverPt,\n        uint256 netLpToBurn\n    ) external returns (uint256 netSyOut, uint256 netPtOut);\n\n    function swapExactPtForSy(\n        address receiver,\n        uint256 exactPtIn,\n        bytes calldata data\n    ) external returns (uint256 netSyOut, uint256 netSyFee);\n\n    function swapSyForExactPt(\n        address receiver,\n        uint256 exactPtOut,\n        bytes calldata data\n    ) external returns (uint256 netSyIn, uint256 netSyFee);\n\n    function redeemRewards(address user) external returns (uint256[] memory);\n\n    function readState(address router) external view returns (MarketState memory market);\n\n    function observe(uint32[] memory secondsAgos) external view returns (uint216[] memory lnImpliedRateCumulative);\n\n    function increaseObservationsCardinalityNext(uint16 cardinalityNext) external;\n\n    function readTokens() external view returns (IStandardizedYield _SY, IPPrincipalToken _PT, IPYieldToken _YT);\n\n    function getRewardTokens() external view returns (address[] memory);\n\n    function isExpired() external view returns (bool);\n\n    function expiry() external view returns (uint256);\n\n    function observations(\n        uint256 index\n    ) external view returns (uint32 blockTimestamp, uint216 lnImpliedRateCumulative, bool initialized);\n\n    function _storage()\n        external\n        view\n        returns (\n            int128 totalPt,\n            int128 totalSy,\n            uint96 lastLnImpliedRate,\n            uint16 observationIndex,\n            uint16 observationCardinality,\n            uint16 observationCardinalityNext\n        );\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPMarketFactoryV3.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IPMarketFactoryV3 {\n    event SetOverriddenFee(address indexed router, address indexed market, uint80 lnFeeRateRoot);\n\n    event CreateNewMarket(\n        address indexed market,\n        address indexed PT,\n        int256 scalarRoot,\n        int256 initialAnchor,\n        uint256 lnFeeRateRoot\n    );\n\n    event NewTreasuryAndFeeReserve(address indexed treasury, uint8 reserveFeePercent);\n\n    function isValidMarket(address market) external view returns (bool);\n\n    // If this is changed, change the readState function in market as well\n    function getMarketConfig(\n        address market,\n        address router\n    ) external view returns (address treasury, uint80 overriddenFee, uint8 reserveFeePercent);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPMarketSwapCallback.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IPMarketSwapCallback {\n    function swapCallback(int256 ptToAccount, int256 syToAccount, bytes calldata data) external;\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPMarketV3.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\nimport \"./IPMarket.sol\";\n\ninterface IPMarketV3 is IPMarket {\n    function getNonOverrideLnFeeRateRoot() external view returns (uint80);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPPrincipalToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface IPPrincipalToken is IERC20Metadata {\n    function burnByYT(address user, uint256 amount) external;\n\n    function mintByYT(address user, uint256 amount) external;\n\n    function initialize(address _YT) external;\n\n    function SY() external view returns (address);\n\n    function YT() external view returns (address);\n\n    function factory() external view returns (address);\n\n    function expiry() external view returns (uint256);\n\n    function isExpired() external view returns (bool);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPVeToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\npragma solidity ^0.8.0;\n\ninterface IPVeToken {\n    // ============= USER INFO =============\n\n    function balanceOf(address user) external view returns (uint128);\n\n    function positionData(address user) external view returns (uint128 amount, uint128 expiry);\n\n    // ============= META DATA =============\n\n    function totalSupplyStored() external view returns (uint128);\n\n    function totalSupplyCurrent() external returns (uint128);\n\n    function totalSupplyAndBalanceCurrent(address user) external returns (uint128, uint128);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IPYieldToken.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"./IRewardManager.sol\";\nimport \"./IPInterestManagerYT.sol\";\n\ninterface IPYieldToken is IERC20Metadata, IRewardManager, IPInterestManagerYT {\n    event NewInterestIndex(uint256 indexed newIndex);\n\n    event Mint(\n        address indexed caller,\n        address indexed receiverPT,\n        address indexed receiverYT,\n        uint256 amountSyToMint,\n        uint256 amountPYOut\n    );\n\n    event Burn(address indexed caller, address indexed receiver, uint256 amountPYToRedeem, uint256 amountSyOut);\n\n    event RedeemRewards(address indexed user, uint256[] amountRewardsOut);\n\n    event RedeemInterest(address indexed user, uint256 interestOut);\n\n    event CollectRewardFee(address indexed rewardToken, uint256 amountRewardFee);\n\n    function mintPY(address receiverPT, address receiverYT) external returns (uint256 amountPYOut);\n\n    function redeemPY(address receiver) external returns (uint256 amountSyOut);\n\n    function redeemPYMulti(\n        address[] calldata receivers,\n        uint256[] calldata amountPYToRedeems\n    ) external returns (uint256[] memory amountSyOuts);\n\n    function redeemDueInterestAndRewards(\n        address user,\n        bool redeemInterest,\n        bool redeemRewards\n    ) external returns (uint256 interestOut, uint256[] memory rewardsOut);\n\n    function rewardIndexesCurrent() external returns (uint256[] memory);\n\n    function pyIndexCurrent() external returns (uint256);\n\n    function pyIndexStored() external view returns (uint256);\n\n    function getRewardTokens() external view returns (address[] memory);\n\n    function SY() external view returns (address);\n\n    function PT() external view returns (address);\n\n    function factory() external view returns (address);\n\n    function expiry() external view returns (uint256);\n\n    function isExpired() external view returns (bool);\n\n    function doCacheIndexSameBlock() external view returns (bool);\n\n    function pyIndexLastUpdatedBlock() external view returns (uint128);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IRewardManager.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\npragma solidity ^0.8.0;\n\ninterface IRewardManager {\n    function userReward(address token, address user) external view returns (uint128 index, uint128 accrued);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IStandardizedYield.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n/*\n * MIT License\n * ===========\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n */\n\npragma solidity ^0.8.0;\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface IStandardizedYield is IERC20Metadata {\n    /// @dev Emitted when any base tokens is deposited to mint shares\n    event Deposit(\n        address indexed caller,\n        address indexed receiver,\n        address indexed tokenIn,\n        uint256 amountDeposited,\n        uint256 amountSyOut\n    );\n\n    /// @dev Emitted when any shares are redeemed for base tokens\n    event Redeem(\n        address indexed caller,\n        address indexed receiver,\n        address indexed tokenOut,\n        uint256 amountSyToRedeem,\n        uint256 amountTokenOut\n    );\n\n    /// @dev check `assetInfo()` for more information\n    enum AssetType {\n        TOKEN,\n        LIQUIDITY\n    }\n\n    /// @dev Emitted when (`user`) claims their rewards\n    event ClaimRewards(address indexed user, address[] rewardTokens, uint256[] rewardAmounts);\n\n    /**\n     * @notice mints an amount of shares by depositing a base token.\n     * @param receiver shares recipient address\n     * @param tokenIn address of the base tokens to mint shares\n     * @param amountTokenToDeposit amount of base tokens to be transferred from (`msg.sender`)\n     * @param minSharesOut reverts if amount of shares minted is lower than this\n     * @return amountSharesOut amount of shares minted\n     * @dev Emits a {Deposit} event\n     *\n     * Requirements:\n     * - (`tokenIn`) must be a valid base token.\n     */\n    function deposit(\n        address receiver,\n        address tokenIn,\n        uint256 amountTokenToDeposit,\n        uint256 minSharesOut\n    ) external payable returns (uint256 amountSharesOut);\n\n    /**\n     * @notice redeems an amount of base tokens by burning some shares\n     * @param receiver recipient address\n     * @param amountSharesToRedeem amount of shares to be burned\n     * @param tokenOut address of the base token to be redeemed\n     * @param minTokenOut reverts if amount of base token redeemed is lower than this\n     * @param burnFromInternalBalance if true, burns from balance of `address(this)`, otherwise burns from `msg.sender`\n     * @return amountTokenOut amount of base tokens redeemed\n     * @dev Emits a {Redeem} event\n     *\n     * Requirements:\n     * - (`tokenOut`) must be a valid base token.\n     */\n    function redeem(\n        address receiver,\n        uint256 amountSharesToRedeem,\n        address tokenOut,\n        uint256 minTokenOut,\n        bool burnFromInternalBalance\n    ) external returns (uint256 amountTokenOut);\n\n    /**\n     * @notice exchangeRate * syBalance / 1e18 must return the asset balance of the account\n     * @notice vice-versa, if a user uses some amount of tokens equivalent to X asset, the amount of sy\n     he can mint must be X * exchangeRate / 1e18\n     * @dev SYUtils's assetToSy & syToAsset should be used instead of raw multiplication\n     & division\n     */\n    function exchangeRate() external view returns (uint256 res);\n\n    /**\n     * @notice claims reward for (`user`)\n     * @param user the user receiving their rewards\n     * @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens`\n     * @dev\n     * Emits a `ClaimRewards` event\n     * See {getRewardTokens} for list of reward tokens\n     */\n    function claimRewards(address user) external returns (uint256[] memory rewardAmounts);\n\n    /**\n     * @notice get the amount of unclaimed rewards for (`user`)\n     * @param user the user to check for\n     * @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens`\n     */\n    function accruedRewards(address user) external view returns (uint256[] memory rewardAmounts);\n\n    function rewardIndexesCurrent() external returns (uint256[] memory indexes);\n\n    function rewardIndexesStored() external view returns (uint256[] memory indexes);\n\n    /**\n     * @notice returns the list of reward token addresses\n     */\n    function getRewardTokens() external view returns (address[] memory);\n\n    /**\n     * @notice returns the address of the underlying yield token\n     */\n    function yieldToken() external view returns (address);\n\n    /**\n     * @notice returns all tokens that can mint this SY\n     */\n    function getTokensIn() external view returns (address[] memory res);\n\n    /**\n     * @notice returns all tokens that can be redeemed by this SY\n     */\n    function getTokensOut() external view returns (address[] memory res);\n\n    function isValidTokenIn(address token) external view returns (bool);\n\n    function isValidTokenOut(address token) external view returns (bool);\n\n    function previewDeposit(\n        address tokenIn,\n        uint256 amountTokenToDeposit\n    ) external view returns (uint256 amountSharesOut);\n\n    function previewRedeem(\n        address tokenOut,\n        uint256 amountSharesToRedeem\n    ) external view returns (uint256 amountTokenOut);\n\n    /**\n     * @notice This function contains information to interpret what the asset is\n     * @return assetType the type of the asset (0 for ERC20 tokens, 1 for AMM liquidity tokens,\n        2 for bridged yield bearing tokens like wstETH, rETH on Arbi whose the underlying asset doesn't exist on the chain)\n     * @return assetAddress the address of the asset\n     * @return assetDecimals the decimals of the asset\n     */\n    function assetInfo() external view returns (AssetType assetType, address assetAddress, uint8 assetDecimals);\n}\n"
      },
      "contracts/pendle/contracts/interfaces/IWETH.sol": {
        "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n/*\n * MIT License\n * ===========\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n */\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IWETH is IERC20 {\n    event Deposit(address indexed dst, uint256 wad);\n    event Withdrawal(address indexed src, uint256 wad);\n\n    function deposit() external payable;\n\n    function withdraw(uint256 wad) external;\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 11000
      },
      "viaIR": true,
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {
        "contracts/pendle/contracts/core/Market/OracleLib.sol": {
          "OracleLib": "0xc6378a93725e499a20df8f00ae31d9ce9d09f1ca"
        }
      }
    }
  }}