{
  "address": "0x6d8b4d49238ffc3Ad23239fbC3045307B98D6F76",
  "abi": [
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "market",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "ptOracle",
          "type": "address"
        },
        {
          "internalType": "enum PendleOracle.RateKind",
          "name": "rateKind",
          "type": "uint8"
        },
        {
          "internalType": "address",
          "name": "ptToken",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "underlyingToken",
          "type": "address"
        },
        {
          "internalType": "address",
          "name": "resilientOracle",
          "type": "address"
        },
        {
          "internalType": "uint32",
          "name": "twapDuration",
          "type": "uint32"
        }
      ],
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "inputs": [],
      "name": "InvalidDuration",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "InvalidTokenAddress",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroAddressNotAllowed",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "ZeroValueNotAllowed",
      "type": "error"
    },
    {
      "inputs": [],
      "name": "CORRELATED_TOKEN",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "MARKET",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "PT_ORACLE",
      "outputs": [
        {
          "internalType": "contract IPendlePtOracle",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "RATE_KIND",
      "outputs": [
        {
          "internalType": "enum PendleOracle.RateKind",
          "name": "",
          "type": "uint8"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "RESILIENT_ORACLE",
      "outputs": [
        {
          "internalType": "contract OracleInterface",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "TWAP_DURATION",
      "outputs": [
        {
          "internalType": "uint32",
          "name": "",
          "type": "uint32"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_DECIMALS",
      "outputs": [
        {
          "internalType": "uint8",
          "name": "",
          "type": "uint8"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "UNDERLYING_TOKEN",
      "outputs": [
        {
          "internalType": "address",
          "name": "",
          "type": "address"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [
        {
          "internalType": "address",
          "name": "asset",
          "type": "address"
        }
      ],
      "name": "getPrice",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],
  "transactionHash": "0x9e745640dfe36ecd0f8ad93eea73b0d63ca82a5236efa2a06a23ebcc4413e533",
  "receipt": {
    "to": null,
    "from": "0x464779C41C5f1Be598853C1F87bCC7087Ea75f28",
    "contractAddress": "0x6d8b4d49238ffc3Ad23239fbC3045307B98D6F76",
    "transactionIndex": 5,
    "gasUsed": "533935",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "blockHash": "0x36da969ebe816a86bc30e3d11ca8cc85288cc98eea9542ae9fe2bc1d52af6462",
    "transactionHash": "0x9e745640dfe36ecd0f8ad93eea73b0d63ca82a5236efa2a06a23ebcc4413e533",
    "logs": [],
    "blockNumber": 49051621,
    "cumulativeGasUsed": "1053225",
    "status": 1,
    "byzantium": true
  },
  "args": [
    "0x0000000000000000000000000000000000000002",
    "0xa37A9127C302fEc17d456a6E1a5643a18a1779aD",
    1,
    "0x14AECeEc177085fd09EA07348B4E1F7Fcc030fA1",
    "0xd2aF6A916Bc77764dc63742BC30f71AF4cF423F4",
    "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823",
    1800
  ],
  "numDeployments": 1,
  "solcInputHash": "5eefab25ac812df21160bd253cc12328",
  "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"market\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"ptOracle\",\"type\":\"address\"},{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"rateKind\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"ptToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"underlyingToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"resilientOracle\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidDuration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroValueNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CORRELATED_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MARKET\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"PT_ORACLE\",\"outputs\":[{\"internalType\":\"contract IPendlePtOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RATE_KIND\",\"outputs\":[{\"internalType\":\"enum PendleOracle.RateKind\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"RESILIENT_ORACLE\",\"outputs\":[{\"internalType\":\"contract OracleInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TWAP_DURATION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_DECIMALS\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"UNDERLYING_TOKEN\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"details\":\"As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\",\"params\":{\"market\":\"Pendle market\",\"ptOracle\":\"Pendle oracle\",\"ptToken\":\"Pendle PT token\",\"rateKind\":\"Either PT_TO_ASSET or PT_TO_SY\",\"resilientOracle\":\"Venus Oracle to get the underlying token price from\",\"twapDuration\":\"TWAP duration to call Pendle oracle with\",\"underlyingToken\":\"Underlying token, can be either the market's asset or the interest bearing token\"}},\"getPrice(address)\":{\"params\":{\"asset\":\"Address of the correlated token\"},\"returns\":{\"_0\":\"price The price of the correlated token in scaled decimal places\"}}},\"stateVariables\":{\"MARKET\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"},\"PT_ORACLE\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"},\"RATE_KIND\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"},\"TWAP_DURATION\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\"},\"UNDERLYING_DECIMALS\":{\"custom:oz-upgrades-unsafe-allow\":\"state-variable-immutable\",\"details\":\"We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"errors\":{\"InvalidDuration()\":[{\"notice\":\"Thrown if the duration is invalid\"}],\"InvalidTokenAddress()\":[{\"notice\":\"Thrown if the token address is invalid\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}],\"ZeroValueNotAllowed()\":[{\"notice\":\"Thrown if the supplied value is 0 where it is not allowed\"}]},\"kind\":\"user\",\"methods\":{\"CORRELATED_TOKEN()\":{\"notice\":\"Address of the correlated token\"},\"MARKET()\":{\"notice\":\"Address of the market\"},\"PT_ORACLE()\":{\"notice\":\"Address of the PT oracle\"},\"RATE_KIND()\":{\"notice\":\"Whether to use PT/SY (standardized yield token) rate or PT/market asset rate\"},\"RESILIENT_ORACLE()\":{\"notice\":\"Address of Resilient Oracle\"},\"TWAP_DURATION()\":{\"notice\":\"Twap duration for the oracle\"},\"UNDERLYING_DECIMALS()\":{\"notice\":\"Decimals of the underlying token\"},\"UNDERLYING_TOKEN()\":{\"notice\":\"Address of the underlying token\"},\"constructor\":{\"notice\":\"Constructor for the implementation contract.\"},\"getPrice(address)\":{\"notice\":\"Fetches the price of the correlated token\"}},\"notice\":\"This oracle fetches the price of a pendle token\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracles/PendleOracle.sol\":\"PendleOracle\"},\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@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\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@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\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@venusprotocol/solidity-utilities/contracts/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Thrown if the supplied value is 0 where it is not allowed\\nerror ZeroValueNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n    if (address_ == address(0)) {\\n        revert ZeroAddressNotAllowed();\\n    }\\n}\\n\\n/// @notice Checks if the provided value is nonzero, reverts otherwise\\n/// @param value_ Value to check\\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\\nfunction ensureNonzeroValue(uint256 value_) pure {\\n    if (value_ == 0) {\\n        revert ZeroValueNotAllowed();\\n    }\\n}\\n\",\"keccak256\":\"0xdb88e14d50dd21889ca3329d755673d022c47e8da005b6a545c7f69c2c4b7b86\",\"license\":\"BSD-3-Clause\"},\"contracts/interfaces/IPendlePtOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\ninterface IPendlePtOracle {\\n    function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n    function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n    function getOracleState(\\n        address market,\\n        uint32 duration\\n    )\\n        external\\n        view\\n        returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\\n}\\n\",\"keccak256\":\"0x14d96d7f75397e4291288ef6367053bd970d95fc0c3e2a028b077f6342e0160a\",\"license\":\"BSD-3-Clause\"},\"contracts/interfaces/OracleInterface.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\ninterface OracleInterface {\\n    function getPrice(address asset) external view returns (uint256);\\n}\\n\\ninterface ResilientOracleInterface is OracleInterface {\\n    function updatePrice(address vToken) external;\\n\\n    function updateAssetPrice(address asset) external;\\n\\n    function getUnderlyingPrice(address vToken) external view returns (uint256);\\n}\\n\\ninterface TwapInterface is OracleInterface {\\n    function updateTwap(address asset) external returns (uint256);\\n}\\n\\ninterface BoundValidatorInterface {\\n    function validatePriceWithAnchorPrice(\\n        address asset,\\n        uint256 reporterPrice,\\n        uint256 anchorPrice\\n    ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x2432799b0d824fc701beb4c30146e912b9aeecf77b5c1635dde6c5fbe6bfc3a7\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/PendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IPendlePtOracle } from \\\"../interfaces/IPendlePtOracle.sol\\\";\\nimport { CorrelatedTokenOracle } from \\\"./common/CorrelatedTokenOracle.sol\\\";\\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title PendleOracle\\n * @author Venus\\n * @notice This oracle fetches the price of a pendle token\\n * @dev As a base price the oracle uses either the price of the Pendle\\n * market's asset (in this case PT_TO_ASSET rate should be used) or\\n * the price of the Pendle market's interest bearing token (e.g. wstETH\\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\\n * interest bearing token is different from standardized yield (SY) token,\\n * but since SY is a wrapper around an interest bearing token, we can safely\\n * assume the prices of the two are equal. This is not always true for asset\\n * price though: using PT_TO_ASSET rate assumes that the yield token can\\n * be seamlessly redeemed for the underlying asset. In reality, this might\\n * not always be the case. For more details, see\\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\\n */\\ncontract PendleOracle is CorrelatedTokenOracle {\\n    /// @notice Which asset to use as a base for the returned PT\\n    /// price. Can be either a standardized yield token (SY), in\\n    /// this case PT/SY price is returned, or the Pendle\\n    /// market's asset directly.\\n    enum RateKind {\\n        PT_TO_ASSET,\\n        PT_TO_SY\\n    }\\n\\n    /// @notice Address of the PT oracle\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    IPendlePtOracle public immutable PT_ORACLE;\\n\\n    /// @notice Whether to use PT/SY (standardized yield token) rate\\n    /// or PT/market asset rate\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    RateKind public immutable RATE_KIND;\\n\\n    /// @notice Address of the market\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    address public immutable MARKET;\\n\\n    /// @notice Twap duration for the oracle\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    uint32 public immutable TWAP_DURATION;\\n\\n    /// @notice Decimals of the underlying token\\n    /// @dev We make an assumption that the underlying decimals will\\n    /// not change throughout the lifetime of the Pendle market\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    uint8 public immutable UNDERLYING_DECIMALS;\\n\\n    /// @notice Thrown if the duration is invalid\\n    error InvalidDuration();\\n\\n    /// @notice Constructor for the implementation contract.\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    /// @param market Pendle market\\n    /// @param ptOracle Pendle oracle\\n    /// @param rateKind Either PT_TO_ASSET or PT_TO_SY\\n    /// @param ptToken Pendle PT token\\n    /// @param underlyingToken Underlying token, can be either the market's asset or the interest bearing token\\n    /// @param resilientOracle Venus Oracle to get the underlying token price from\\n    /// @param twapDuration TWAP duration to call Pendle oracle with\\n    constructor(\\n        address market,\\n        address ptOracle,\\n        RateKind rateKind,\\n        address ptToken,\\n        address underlyingToken,\\n        address resilientOracle,\\n        uint32 twapDuration\\n    ) CorrelatedTokenOracle(ptToken, underlyingToken, resilientOracle) {\\n        ensureNonzeroAddress(market);\\n        ensureNonzeroAddress(ptOracle);\\n        ensureNonzeroValue(twapDuration);\\n\\n        MARKET = market;\\n        PT_ORACLE = IPendlePtOracle(ptOracle);\\n        RATE_KIND = rateKind;\\n        TWAP_DURATION = twapDuration;\\n        UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\\n\\n        (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\\n            MARKET,\\n            TWAP_DURATION\\n        );\\n        if (increaseCardinalityRequired || !oldestObservationSatisfied) {\\n            revert InvalidDuration();\\n        }\\n    }\\n\\n    /// @notice Fetches the amount of underlying token for 1 PT\\n    /// @return amount The amount of underlying token (either the market's asset\\n    /// or the yield token) for 1 PT, adjusted for decimals such that the result\\n    /// has the same precision as the underlying token\\n    function _getUnderlyingAmount() internal view override returns (uint256) {\\n        uint256 rate;\\n        if (RATE_KIND == RateKind.PT_TO_SY) {\\n            rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\\n        } else {\\n            rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\\n        }\\n        return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\\n    }\\n}\\n\",\"keccak256\":\"0x46795f6ccb516156556008bf32052edd24c3239fcd2ca139c326f57d04bf0ed0\",\"license\":\"BSD-3-Clause\"},\"contracts/oracles/common/CorrelatedTokenOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { OracleInterface } from \\\"../../interfaces/OracleInterface.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\nimport { IERC20Metadata } from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\n\\n/**\\n * @title CorrelatedTokenOracle\\n * @notice This oracle fetches the price of a token that is correlated to another token.\\n */\\nabstract contract CorrelatedTokenOracle is OracleInterface {\\n    /// @notice Address of the correlated token\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    address public immutable CORRELATED_TOKEN;\\n\\n    /// @notice Address of the underlying token\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    address public immutable UNDERLYING_TOKEN;\\n\\n    /// @notice Address of Resilient Oracle\\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\\n    OracleInterface public immutable RESILIENT_ORACLE;\\n\\n    /// @notice Thrown if the token address is invalid\\n    error InvalidTokenAddress();\\n\\n    /// @notice Constructor for the implementation contract.\\n    /// @custom:oz-upgrades-unsafe-allow constructor\\n    constructor(address correlatedToken, address underlyingToken, address resilientOracle) {\\n        ensureNonzeroAddress(correlatedToken);\\n        ensureNonzeroAddress(underlyingToken);\\n        ensureNonzeroAddress(resilientOracle);\\n        CORRELATED_TOKEN = correlatedToken;\\n        UNDERLYING_TOKEN = underlyingToken;\\n        RESILIENT_ORACLE = OracleInterface(resilientOracle);\\n    }\\n\\n    /**\\n     * @notice Fetches the price of the correlated token\\n     * @param asset Address of the correlated token\\n     * @return price The price of the correlated token in scaled decimal places\\n     */\\n    function getPrice(address asset) external view override returns (uint256) {\\n        if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress();\\n\\n        // get underlying token amount for 1 correlated token scaled by underlying token decimals\\n        uint256 underlyingAmount = _getUnderlyingAmount();\\n\\n        // oracle returns (36 - asset decimal) scaled price\\n        uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN);\\n\\n        IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN);\\n        uint256 decimals = token.decimals();\\n\\n        // underlyingAmount (for 1 correlated token) * underlyingUSDPrice / decimals(correlated token)\\n        return (underlyingAmount * underlyingUSDPrice) / (10 ** decimals);\\n    }\\n\\n    /**\\n     * @notice Gets the underlying amount for correlated token\\n     * @return underlyingAmount Amount of underlying token\\n     */\\n    function _getUnderlyingAmount() internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0x7053239c18747f7439e025cd4aab629f78dd6dbaadeedacf2393d74c4db317ca\",\"license\":\"BSD-3-Clause\"}},\"version\":1}",
  "bytecode": "0x610180604052348015610010575f80fd5b50604051610c8b380380610c8b83398101604081905261002f91610265565b83838361003b83610200565b61004482610200565b61004d81610200565b6001600160a01b0392831660805290821660a0521660c05261006e87610200565b61007786610200565b61008663ffffffff821661022a565b6001600160a01b0380881661012052861660e0528460018111156100ac576100ac6102f7565b6101008160018111156100c1576100c16102f7565b815250508063ffffffff166101408163ffffffff168152505060a0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610118573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061013c919061030b565b60ff166101605260e051610120516101405160405162439f4b60e91b81526001600160a01b03928316600482015263ffffffff90911660248201525f928392169063873e960090604401606060405180830381865afa1580156101a1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101c59190610341565b925050915081806101d4575080155b156101f257604051637616640160e01b815260040160405180910390fd5b505050505050505050610389565b6001600160a01b038116610227576040516342bcdf7f60e11b815260040160405180910390fd5b50565b805f036102275760405163273e150360e21b815260040160405180910390fd5b80516001600160a01b0381168114610260575f80fd5b919050565b5f805f805f805f60e0888a03121561027b575f80fd5b6102848861024a565b96506102926020890161024a565b95506040880151600281106102a5575f80fd5b94506102b36060890161024a565b93506102c16080890161024a565b92506102cf60a0890161024a565b915060c088015163ffffffff811681146102e7575f80fd5b8091505092959891949750929550565b634e487b7160e01b5f52602160045260245ffd5b5f6020828403121561031b575f80fd5b815160ff8116811461032b575f80fd5b9392505050565b80518015158114610260575f80fd5b5f805f60608486031215610353575f80fd5b61035c84610332565b9250602084015161ffff81168114610372575f80fd5b915061038060408501610332565b90509250925092565b60805160a05160c05160e051610100516101205161014051610160516108556104365f395f818161011501526105fc01525f81816101bd0152818161047a015261055501525f818161022001528181610452015261052d01525f81816099015261040601525f8181610196015281816104a6015261058101525f81816101f901526102e201525f818160d601526102b501525f818161016f01528181610245015261035001526108555ff3fe608060405234801561000f575f80fd5b5060043610610090575f3560e01c806369818a351161006357806369818a351461016a578063809d7b3114610191578063879ac8f8146101b8578063a4edcd4c146101f4578063f46f16c21461021b575f80fd5b806302125d091461009457806329db1be6146100d15780633dae7c221461011057806341976e0914610149575b5f80fd5b6100bb7f000000000000000000000000000000000000000000000000000000000000000081565b6040516100c89190610650565b60405180910390f35b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c8565b6101377f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100c8565b61015c610157366004610676565b610242565b6040519081526020016100c8565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6101df7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016100c8565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461029557604051630f58058360e11b815260040160405180910390fd5b5f61029e610400565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529192505f917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610327573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034b91906106a3565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103d291906106ba565b60ff1690506103e281600a6107d0565b6103ec84866107db565b6103f691906107f2565b9695505050505050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156104365761043661063c565b036105165760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa1580156104eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061050f91906106a3565b90506105ed565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156105c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105ea91906106a3565b90505b670de0b6b3a7640000816106227f0000000000000000000000000000000000000000000000000000000000000000600a610811565b61062c91906107db565b61063691906107f2565b91505090565b634e487b7160e01b5f52602160045260245ffd5b602081016002831061067057634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610686575f80fd5b81356001600160a01b038116811461069c575f80fd5b9392505050565b5f602082840312156106b3575f80fd5b5051919050565b5f602082840312156106ca575f80fd5b815160ff8116811461069c575f80fd5b634e487b7160e01b5f52601160045260245ffd5b600181815b8085111561072857815f190482111561070e5761070e6106da565b8085161561071b57918102915b93841c93908002906106f3565b509250929050565b5f8261073e575060016107ca565b8161074a57505f6107ca565b8160018114610760576002811461076a57610786565b60019150506107ca565b60ff84111561077b5761077b6106da565b50506001821b6107ca565b5060208310610133831016604e8410600b84101617156107a9575081810a6107ca565b6107b383836106ee565b805f19048211156107c6576107c66106da565b0290505b92915050565b5f61069c8383610730565b80820281158282048414176107ca576107ca6106da565b5f8261080c57634e487b7160e01b5f52601260045260245ffd5b500490565b5f61069c60ff84168361073056fea2646970667358221220fe2f95210623d570bf7d8df3a30805830eecd7ccb7031d8bd1c944565c5f5f6a64736f6c63430008190033",
  "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610090575f3560e01c806369818a351161006357806369818a351461016a578063809d7b3114610191578063879ac8f8146101b8578063a4edcd4c146101f4578063f46f16c21461021b575f80fd5b806302125d091461009457806329db1be6146100d15780633dae7c221461011057806341976e0914610149575b5f80fd5b6100bb7f000000000000000000000000000000000000000000000000000000000000000081565b6040516100c89190610650565b60405180910390f35b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016100c8565b6101377f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016100c8565b61015c610157366004610676565b610242565b6040519081526020016100c8565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6101df7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016100c8565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b6100f87f000000000000000000000000000000000000000000000000000000000000000081565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461029557604051630f58058360e11b815260040160405180910390fd5b5f61029e610400565b6040516341976e0960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529192505f917f000000000000000000000000000000000000000000000000000000000000000016906341976e0990602401602060405180830381865afa158015610327573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034b91906106a3565b90505f7f000000000000000000000000000000000000000000000000000000000000000090505f816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ae573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103d291906106ba565b60ff1690506103e281600a6107d0565b6103ec84866107db565b6103f691906107f2565b9695505050505050565b5f8060017f000000000000000000000000000000000000000000000000000000000000000060018111156104365761043661063c565b036105165760405163a31426d160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063a31426d190604401602060405180830381865afa1580156104eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061050f91906106a3565b90506105ed565b60405163abca0eab60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156105c6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105ea91906106a3565b90505b670de0b6b3a7640000816106227f0000000000000000000000000000000000000000000000000000000000000000600a610811565b61062c91906107db565b61063691906107f2565b91505090565b634e487b7160e01b5f52602160045260245ffd5b602081016002831061067057634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215610686575f80fd5b81356001600160a01b038116811461069c575f80fd5b9392505050565b5f602082840312156106b3575f80fd5b5051919050565b5f602082840312156106ca575f80fd5b815160ff8116811461069c575f80fd5b634e487b7160e01b5f52601160045260245ffd5b600181815b8085111561072857815f190482111561070e5761070e6106da565b8085161561071b57918102915b93841c93908002906106f3565b509250929050565b5f8261073e575060016107ca565b8161074a57505f6107ca565b8160018114610760576002811461076a57610786565b60019150506107ca565b60ff84111561077b5761077b6106da565b50506001821b6107ca565b5060208310610133831016604e8410600b84101617156107a9575081810a6107ca565b6107b383836106ee565b805f19048211156107c6576107c66106da565b0290505b92915050565b5f61069c8383610730565b80820281158282048414176107ca576107ca6106da565b5f8261080c57634e487b7160e01b5f52601260045260245ffd5b500490565b5f61069c60ff84168361073056fea2646970667358221220fe2f95210623d570bf7d8df3a30805830eecd7ccb7031d8bd1c944565c5f5f6a64736f6c63430008190033",
  "devdoc": {
    "author": "Venus",
    "details": "As a base price the oracle uses either the price of the Pendle market's asset (in this case PT_TO_ASSET rate should be used) or the price of the Pendle market's interest bearing token (e.g. wstETH for stETH; in this case PT_TO_SY rate should be used). Technically, interest bearing token is different from standardized yield (SY) token, but since SY is a wrapper around an interest bearing token, we can safely assume the prices of the two are equal. This is not always true for asset price though: using PT_TO_ASSET rate assumes that the yield token can be seamlessly redeemed for the underlying asset. In reality, this might not always be the case. For more details, see https://docs.pendle.finance/Developers/Contracts/StandardizedYield",
    "kind": "dev",
    "methods": {
      "constructor": {
        "custom:oz-upgrades-unsafe-allow": "constructor",
        "params": {
          "market": "Pendle market",
          "ptOracle": "Pendle oracle",
          "ptToken": "Pendle PT token",
          "rateKind": "Either PT_TO_ASSET or PT_TO_SY",
          "resilientOracle": "Venus Oracle to get the underlying token price from",
          "twapDuration": "TWAP duration to call Pendle oracle with",
          "underlyingToken": "Underlying token, can be either the market's asset or the interest bearing token"
        }
      },
      "getPrice(address)": {
        "params": {
          "asset": "Address of the correlated token"
        },
        "returns": {
          "_0": "price The price of the correlated token in scaled decimal places"
        }
      }
    },
    "stateVariables": {
      "MARKET": {
        "custom:oz-upgrades-unsafe-allow": "state-variable-immutable"
      },
      "PT_ORACLE": {
        "custom:oz-upgrades-unsafe-allow": "state-variable-immutable"
      },
      "RATE_KIND": {
        "custom:oz-upgrades-unsafe-allow": "state-variable-immutable"
      },
      "TWAP_DURATION": {
        "custom:oz-upgrades-unsafe-allow": "state-variable-immutable"
      },
      "UNDERLYING_DECIMALS": {
        "custom:oz-upgrades-unsafe-allow": "state-variable-immutable",
        "details": "We make an assumption that the underlying decimals will not change throughout the lifetime of the Pendle market"
      }
    },
    "title": "PendleOracle",
    "version": 1
  },
  "userdoc": {
    "errors": {
      "InvalidDuration()": [
        {
          "notice": "Thrown if the duration is invalid"
        }
      ],
      "InvalidTokenAddress()": [
        {
          "notice": "Thrown if the token address is invalid"
        }
      ],
      "ZeroAddressNotAllowed()": [
        {
          "notice": "Thrown if the supplied address is a zero address where it is not allowed"
        }
      ],
      "ZeroValueNotAllowed()": [
        {
          "notice": "Thrown if the supplied value is 0 where it is not allowed"
        }
      ]
    },
    "kind": "user",
    "methods": {
      "CORRELATED_TOKEN()": {
        "notice": "Address of the correlated token"
      },
      "MARKET()": {
        "notice": "Address of the market"
      },
      "PT_ORACLE()": {
        "notice": "Address of the PT oracle"
      },
      "RATE_KIND()": {
        "notice": "Whether to use PT/SY (standardized yield token) rate or PT/market asset rate"
      },
      "RESILIENT_ORACLE()": {
        "notice": "Address of Resilient Oracle"
      },
      "TWAP_DURATION()": {
        "notice": "Twap duration for the oracle"
      },
      "UNDERLYING_DECIMALS()": {
        "notice": "Decimals of the underlying token"
      },
      "UNDERLYING_TOKEN()": {
        "notice": "Address of the underlying token"
      },
      "constructor": {
        "notice": "Constructor for the implementation contract."
      },
      "getPrice(address)": {
        "notice": "Fetches the price of the correlated token"
      }
    },
    "notice": "This oracle fetches the price of a pendle token",
    "version": 1
  },
  "storageLayout": {
    "storage": [],
    "types": null
  }
}
