fluid-contracts-public/deployments/mainnet/dump/0x96B7F148d86048688AA8414f9D01e3B4C41786aB.json
2024-07-11 13:05:09 +00:00

219 lines
46 KiB
JSON

{
"address": "0x96B7F148d86048688AA8414f9D01e3B4C41786aB",
"abi": [
{
"inputs": [
{
"internalType": "contract IPendlePYLpOracle",
"name": "pendleOracle_",
"type": "address"
},
{
"internalType": "contract IPendleMarketV3",
"name": "pendleMarket_",
"type": "address"
},
{
"internalType": "uint32",
"name": "twapDuration_",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "maxExpectedBorrowRate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minYieldRate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxYieldRate_",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "debtTokenDecimals_",
"type": "uint8"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "errorId_",
"type": "uint256"
}
],
"name": "FluidOracleError",
"type": "error"
},
{
"inputs": [],
"name": "getExchangeRate",
"outputs": [
{
"internalType": "uint256",
"name": "exchangeRate_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getExchangeRateLiquidate",
"outputs": [
{
"internalType": "uint256",
"name": "exchangeRate_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getExchangeRateOperate",
"outputs": [
{
"internalType": "uint256",
"name": "exchangeRate_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pendleOracleData",
"outputs": [
{
"internalType": "contract IPendlePYLpOracle",
"name": "pendleOracle_",
"type": "address"
},
{
"internalType": "contract IPendleMarketV3",
"name": "pendleMarket_",
"type": "address"
},
{
"internalType": "uint256",
"name": "expiry_",
"type": "uint256"
},
{
"internalType": "uint32",
"name": "twapDuration_",
"type": "uint32"
},
{
"internalType": "uint256",
"name": "maxExpectedBorrowRate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minYieldRate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maxYieldRate_",
"type": "uint256"
},
{
"internalType": "uint8",
"name": "debtTokenDecimals_",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "exchangeRateOperate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "exchangeRateLiquidate_",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "ptToAssetRateTWAP_",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x7592e9551ada3f7f345b99349294f410e1c1d8b6a20875ba061998fed4e6b3cf",
"receipt": {
"to": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"from": "0x0Ed35B1609Ec45c7079E80d11149a52717e4859A",
"contractAddress": null,
"transactionIndex": 103,
"gasUsed": "668695",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0x8967d4b3f18f7f1680893100870052aaf014a7ff2291f01760ac28804a37b63a",
"transactionHash": "0x7592e9551ada3f7f345b99349294f410e1c1d8b6a20875ba061998fed4e6b3cf",
"logs": [],
"blockNumber": 20160402,
"cumulativeGasUsed": "8378675",
"status": 1,
"byzantium": true
},
"args": [
"0x9a9Fa8338dd5E5B2188006f1Cd2Ef26d921650C2",
"0xd1D7D99764f8a52Aff007b7831cc02748b2013b5",
900,
4000,
860,
7180,
6
],
"numDeployments": 1,
"solcInputHash": "fc72f80b97f3c794d054ad22f251b291",
"metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IPendlePYLpOracle\",\"name\":\"pendleOracle_\",\"type\":\"address\"},{\"internalType\":\"contract IPendleMarketV3\",\"name\":\"pendleMarket_\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration_\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"maxExpectedBorrowRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minYieldRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxYieldRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"debtTokenDecimals_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"errorId_\",\"type\":\"uint256\"}],\"name\":\"FluidOracleError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"getExchangeRate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExchangeRateLiquidate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExchangeRateOperate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"exchangeRate_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendleOracleData\",\"outputs\":[{\"internalType\":\"contract IPendlePYLpOracle\",\"name\":\"pendleOracle_\",\"type\":\"address\"},{\"internalType\":\"contract IPendleMarketV3\",\"name\":\"pendleMarket_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"expiry_\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"twapDuration_\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"maxExpectedBorrowRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minYieldRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxYieldRate_\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"debtTokenDecimals_\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"exchangeRateOperate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"exchangeRateLiquidate_\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ptToAssetRateTWAP_\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getExchangeRate()\":{\"details\":\"Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for backwards compatibility.\"}},\"title\":\"PendleOracle\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"getExchangeRateLiquidate()\":{\"notice\":\"Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations\"},\"getExchangeRateOperate()\":{\"notice\":\"Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates\"},\"pendleOracleData()\":{\"notice\":\"returns all Pendle oracle related data as utility for easy off-chain use / block explorer in a single view method\"}},\"notice\":\"Gets the exchange rate between Pendle and the underlying asset for the Pendle Market.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracle/oracles/pendleOracle.sol\":\"PendleOracle\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":10000000},\"remappings\":[]},\"sources\":{\"contracts/oracle/error.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\ncontract Error {\\n error FluidOracleError(uint256 errorId_);\\n}\\n\",\"keccak256\":\"0xc7b7e945238168d216c480e9dd4fbaaf8780645d58c47f9abdaa4f29910568fe\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/errorTypes.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nlibrary ErrorTypes {\\n /***********************************|\\n | UniV3CheckCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the delta between main price source and check rate source is exceeding the allowed delta\\n uint256 internal constant UniV3CheckCLRSOracle__InvalidPrice = 60001;\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant UniV3CheckCLRSOracle__InvalidParams = 60002;\\n\\n /// @notice thrown when the exchange rate is zero, even after all possible fallbacks depending on config\\n uint256 internal constant UniV3CheckCLRSOracle__ExchangeRateZero = 60003;\\n\\n /***********************************|\\n | sUSDe Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant SUSDeOracle__InvalidParams = 60102;\\n\\n /***********************************|\\n | Pendle Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant PendleOracle__InvalidParams = 60201;\\n\\n /// @notice thrown when the Pendle market Oracle has not been initialized yet\\n uint256 internal constant PendleOracle__MarketNotInitialized = 60202;\\n\\n /// @notice thrown when the Pendle market does not have 18 decimals\\n uint256 internal constant PendleOracle__MarketInvalidDecimals = 60203;\\n\\n /// @notice thrown when the Pendle market returns an unexpected price\\n uint256 internal constant PendleOracle__InvalidPrice = 60204;\\n\\n /***********************************|\\n | Chainlink Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant ChainlinkOracle__InvalidParams = 61001;\\n\\n /***********************************|\\n | UniswapV3 Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant UniV3Oracle__InvalidParams = 62001;\\n\\n /// @notice thrown when constructor is called with invalid ordered seconds agos values\\n uint256 internal constant UniV3Oracle__InvalidSecondsAgos = 62002;\\n\\n /// @notice thrown when constructor is called with invalid delta values > 100%\\n uint256 internal constant UniV3Oracle__InvalidDeltas = 62003;\\n\\n /***********************************|\\n | WstETh Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant WstETHOracle__InvalidParams = 63001;\\n\\n /***********************************|\\n | Redstone Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant RedstoneOracle__InvalidParams = 64001;\\n\\n /***********************************|\\n | Fallback Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant FallbackOracle__InvalidParams = 65001;\\n\\n /***********************************|\\n | FallbackCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\\n uint256 internal constant FallbackCLRSOracle__ExchangeRateZero = 66001;\\n\\n /***********************************|\\n | WstETHCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the fallback oracle source (if enabled)\\n uint256 internal constant WstETHCLRSOracle__ExchangeRateZero = 67001;\\n\\n /***********************************|\\n | CLFallbackUniV3Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\\n uint256 internal constant CLFallbackUniV3Oracle__ExchangeRateZero = 68001;\\n\\n /***********************************|\\n | WstETHCLRS2UniV3CheckCLRSOracle | \\n |__________________________________*/\\n\\n /// @notice thrown when the exchange rate is zero, even for the uniV3 rate\\n uint256 internal constant WstETHCLRS2UniV3CheckCLRSOracle__ExchangeRateZero = 69001;\\n\\n /***********************************|\\n | WeETh Oracle | \\n |__________________________________*/\\n\\n /// @notice thrown when an invalid parameter is passed to a method\\n uint256 internal constant WeETHOracle__InvalidParams = 70001;\\n}\\n\",\"keccak256\":\"0x47e93f080093faa70d943affcd173500f06275348429de61031bc598c2edeb1b\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/fluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IFluidOracle } from \\\"./interfaces/iFluidOracle.sol\\\";\\n\\n/// @title FluidOracle\\n/// @notice Base contract that any Fluid Oracle must implement\\nabstract contract FluidOracle is IFluidOracle {\\n /// @inheritdoc IFluidOracle\\n function getExchangeRate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateOperate() external view virtual returns (uint256 exchangeRate_);\\n\\n /// @inheritdoc IFluidOracle\\n function getExchangeRateLiquidate() external view virtual returns (uint256 exchangeRate_);\\n}\\n\",\"keccak256\":\"0xd275b5b0ada86c81a4dc6c79a24b1cb8bcfc374f4856e08917bf1bae83574b37\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/implementations/pendleOracleImpl.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { IPendleMarketV3 } from \\\"../interfaces/external/IPendleMarketV3.sol\\\";\\nimport { IPendlePYLpOracle } from \\\"../interfaces/external/IPendlePYLpOracle.sol\\\";\\nimport { ErrorTypes } from \\\"../errorTypes.sol\\\";\\nimport { Error as OracleError } from \\\"../error.sol\\\";\\nimport { OracleUtils } from \\\"../libraries/oracleUtils.sol\\\";\\n\\n/// @title Pendle Oracle implementation\\n/// @notice This contract is used to get the exchange rate for a Pendle market (PT-Asset).\\nabstract contract PendleOracleImpl is OracleError {\\n /// @dev Pendle pyYtLpOracle address, see Pendle docs for deployment address.\\n IPendlePYLpOracle internal immutable _PENDLE_ORACLE;\\n\\n /// @dev Pendle market address for which this Oracle is intended for.\\n IPendleMarketV3 internal immutable _PENDLE_MARKET;\\n\\n /// @dev timestamp when PT reaches maturity. read and stored from Immutable at the `_PENDLE_MARKET` contract.\\n uint256 internal immutable _EXPIRY;\\n\\n /// @dev TWAP duration for the pendle AMM oracle rate fetch.\\n /// The recommended duration is 15 mins (900 secs) or 30 mins (1800 secs), but it can vary depending on the market.\\n /// See https://docs.pendle.finance/Developers/Oracles/HowToIntegratePtAndLpOracle#second-choose-a-market--duration\\n uint32 internal immutable _TWAP_DURATION;\\n\\n /// @dev maximum expected borrow rate for the borrow asset at the Fluid vault. Affects the increasing price for\\n /// operate(), creating an effective CF at the vault that increases as we get closer to maturity.\\n uint256 internal immutable _MAX_EXPECTED_BORROW_RATE;\\n\\n /// @dev minimum ever expected yield rate at Pendle for the PT asset. If TWAP price is outside of this range,\\n /// the oracle will revert, stopping any new borrows during a time of unexpected state of the Pendle market.\\n uint256 internal immutable _MIN_YIELD_RATE;\\n\\n /// @dev maximum ever expected yield rate at Pendle for the PT asset. If TWAP price is outside of this range,\\n /// the oracle will revert, stopping any new borrows during a time of unexpected state of the Pendle market.\\n uint256 internal immutable _MAX_YIELD_RATE;\\n\\n /// @dev decimals of the debt token for correct scaling out the output rate\\n uint8 internal immutable _DEBT_TOKEN_DECIMALS;\\n\\n uint8 internal constant _PENDLE_DECIMALS = 18;\\n\\n constructor(\\n IPendlePYLpOracle pendleOracle_,\\n IPendleMarketV3 pendleMarket_,\\n uint32 twapDuration_,\\n uint256 maxExpectedBorrowRate_,\\n uint256 minYieldRate_,\\n uint256 maxYieldRate_,\\n uint8 debtTokenDecimals_\\n ) {\\n if (\\n address(pendleOracle_) == address(0) ||\\n address(pendleMarket_) == address(0) ||\\n twapDuration_ == 0 ||\\n // human input sanity checks:\\n // max expected yield / borrow rate values should be >0 and below 300% (<100% for min yield rate)\\n maxExpectedBorrowRate_ == 0 ||\\n maxExpectedBorrowRate_ > 300 * 1e2 ||\\n minYieldRate_ == 0 ||\\n minYieldRate_ > 100 * 1e2 ||\\n maxYieldRate_ == 0 ||\\n maxYieldRate_ > 300 * 1e2 ||\\n minYieldRate_ > maxYieldRate_ ||\\n debtTokenDecimals_ < 6\\n ) {\\n revert FluidOracleError(ErrorTypes.PendleOracle__InvalidParams);\\n }\\n\\n {\\n (bool increaseCardinalityRequired_, , bool oldestObservationSatisfied_) = pendleOracle_.getOracleState(\\n address(pendleMarket_),\\n twapDuration_\\n );\\n if (increaseCardinalityRequired_ || !oldestObservationSatisfied_) {\\n // ensure pendle market Oracle is ready and initialized see\\n // https://docs.pendle.finance/Developers/Oracles/HowToIntegratePtAndLpOracle\\n revert FluidOracleError(ErrorTypes.PendleOracle__MarketNotInitialized);\\n }\\n }\\n\\n if (\\n pendleMarket_.decimals() != _PENDLE_DECIMALS ||\\n // getPtToAssetRate should be returned in 1e18, otherwise this oracle will be faulty.\\n // if the returned price is < 1e15, decimals are off and the issue should be investigated.\\n pendleOracle_.getPtToAssetRate(address(pendleMarket_), twapDuration_) < 1e15\\n ) {\\n // pendle market should have 18 decimals, other markets currently don't exist. If different, might have to adjust\\n // code so better to sanity check & revert.\\n revert FluidOracleError(ErrorTypes.PendleOracle__MarketInvalidDecimals);\\n }\\n\\n _PENDLE_ORACLE = pendleOracle_;\\n _PENDLE_MARKET = pendleMarket_;\\n _EXPIRY = pendleMarket_.expiry();\\n _TWAP_DURATION = twapDuration_;\\n _MAX_EXPECTED_BORROW_RATE = maxExpectedBorrowRate_;\\n _MIN_YIELD_RATE = minYieldRate_;\\n _MAX_YIELD_RATE = maxYieldRate_;\\n\\n // debt token decimals is used to make sure the returned exchange rate is scaled correctly e.g.\\n // for an exchange rate between PT-sUSDe and USDC (this Oracle returning amount of USDC for 1e18 PT-sUSDe).\\n _DEBT_TOKEN_DECIMALS = debtTokenDecimals_;\\n }\\n\\n /// @dev returns the pendle oracle exchange rate for operate() scaled by `OracleUtils.RATE_OUTPUT_DECIMALS`.\\n /// checks that the AMM TWAP rate at Pendle is within the allowed yield ranges, and returns\\n /// the `rate_` based on maturity and a maximum expected borrow rate at Fluid, resulting into an automatically\\n /// with block.timestamp adjusting effective CF at the vault, increasing as we get closer to maturity.\\n function _getPendleExchangeRateOperate() internal view returns (uint256 rate_) {\\n uint256 timeToMaturity_;\\n unchecked {\\n timeToMaturity_ = _EXPIRY > block.timestamp ? _EXPIRY - block.timestamp : 0;\\n }\\n if (timeToMaturity_ == 0) {\\n // at maturity, 1PT is always 1 underlying.\\n return (10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + _DEBT_TOKEN_DECIMALS)) / (10 ** _PENDLE_DECIMALS);\\n }\\n\\n // get TWAP price from Pendle AMM.\\n // Note getPtToAssetRate() gives the price of PT to the underlying asset at maturity.\\n // For PT-sUSDe this would be USDe, not sUSDe (sUSDe -> USDe fetched from contract pricing)!\\n rate_ =\\n _PENDLE_ORACLE.getPtToAssetRate(address(_PENDLE_MARKET), _TWAP_DURATION) *\\n (10 ** (OracleUtils.RATE_OUTPUT_DECIMALS - _PENDLE_DECIMALS)); // * 1e9 to scale to 1e27\\n // check if within allowed ranges\\n // 1PT can never be more than 1:1 to asset,\\n if (rate_ > 10 ** OracleUtils.RATE_OUTPUT_DECIMALS) {\\n // this should never happen, even at maturity the max price would be 1:1\\n revert FluidOracleError(ErrorTypes.PendleOracle__InvalidPrice);\\n }\\n\\n // price should be within _MIN_YIELD_RATE & _MAX_YIELD_RATE for time to maturity.\\n // Note max yield results in a smaller price for the PT asset and vice versa for min.\\n uint256 minExpectedPrice_ = _priceAtRateToMaturity(_MAX_YIELD_RATE, timeToMaturity_);\\n uint256 maxExpectedPrice_ = _priceAtRateToMaturity(_MIN_YIELD_RATE, timeToMaturity_);\\n\\n if (rate_ < minExpectedPrice_ || rate_ > maxExpectedPrice_) {\\n revert FluidOracleError(ErrorTypes.PendleOracle__InvalidPrice);\\n }\\n\\n // for operate return peg price based on maturity and a maximum expected borrow rate at Fluid. This results in\\n // an effective decreased CF at the vault depending on time to maturity.\\n // example for a Fluid vault PT-SUSDE / USDC, as we assume price at maturity:\\n // 1 PT-SUSDE = 1 USDE and 1 USDE = 1 USDC. where this oracle is responsible for the 1 PT-SUSDE = 1 USDE part.\\n // with a CF of 85% at the vault, that means a user can borrow 0.85 USDC for 1 PT-SUSDE.\\n // Our goal is to guarantee there is no possibility for bad debt at maturity. So effective CF should be time dependent to maturity\\n // based on a max expected borrow rate.\\n // e.g. at 50% max borrow rate and maturity in 100 days, _priceAtRateToMaturity would return:\\n // x = 1e20 * 1e27 / (1e20 + (5000 * 1e16 * 100 days / 365 days)) = 879518072289156626\\n\\n // now this oracle reports instead of 1 PT-SUSDE = 1 USDE, 1 PT-SUSDE = 0.879518072289156626 USDE.\\n // which leads to a user can borrow 0.879518072289156626 USDE * 0.85 CF = 0.747590361445783132 USDC for 1 PT-SUSDE.\\n\\n // this automatically adjusts the closer we get to maturity. E.g. at 1 day to maturity:\\n // x = 1e20 * 1e27 / (1e20 + (5000 * 1e16 * 1 days / 365 days)) = 998632010943912448\\n // -> user can borrow 0.998632010943912448 USDE * 0.85 CF = 0.848837209302325581 USDC for 1 PT-SUSDE.\\n\\n rate_ = _priceAtRateToMaturity(_MAX_EXPECTED_BORROW_RATE, timeToMaturity_);\\n // scale result:\\n // e.g. for PT-SUSDE -> USDC: rate * 10^6 / 10^18 = result will be in 1e15\\n // e.g. for PT-SUSDE -> DAI: rate * 10^18 / 10^18 = result will be in 1e27\\n rate_ = (rate_ * (10 ** _DEBT_TOKEN_DECIMALS)) / (10 ** _PENDLE_DECIMALS);\\n }\\n\\n /// @dev returns the pendle oracle exchange rate for liquidate(): 1PT = 1 underlying (e.g. 1PT-sUSDE = 1 USDE).\\n /// scaled by `OracleUtils.RATE_OUTPUT_DECIMALS`.\\n function _getPendleExchangeRateLiquidate() internal view returns (uint256 rate_) {\\n // for liquidate, peg at maturity is assumed: 1PT = 1 underlying (e.g. 1PT-sUSDE = 1 USDE).\\n // this avoids unnecessary liquidation cascades. Any bad debt would be temporary until maturity only.\\n // see scaling info in `_getPendleExchangeRateOperate()`\\n return (10 ** (OracleUtils.RATE_OUTPUT_DECIMALS + _DEBT_TOKEN_DECIMALS)) / (10 ** _PENDLE_DECIMALS);\\n }\\n\\n /// @notice returns all Pendle oracle related data as utility for easy off-chain use / block explorer in a single view method\\n function pendleOracleData()\\n public\\n view\\n returns (\\n IPendlePYLpOracle pendleOracle_,\\n IPendleMarketV3 pendleMarket_,\\n uint256 expiry_,\\n uint32 twapDuration_,\\n uint256 maxExpectedBorrowRate_,\\n uint256 minYieldRate_,\\n uint256 maxYieldRate_,\\n uint8 debtTokenDecimals_,\\n uint256 exchangeRateOperate_,\\n uint256 exchangeRateLiquidate_,\\n uint256 ptToAssetRateTWAP_\\n )\\n {\\n return (\\n _PENDLE_ORACLE,\\n _PENDLE_MARKET,\\n _EXPIRY,\\n _TWAP_DURATION,\\n _MAX_EXPECTED_BORROW_RATE,\\n _MIN_YIELD_RATE,\\n _MAX_YIELD_RATE,\\n _DEBT_TOKEN_DECIMALS,\\n _getPendleExchangeRateOperate(),\\n _getPendleExchangeRateLiquidate(),\\n _PENDLE_ORACLE.getPtToAssetRate(address(_PENDLE_MARKET), _TWAP_DURATION)\\n );\\n }\\n\\n /// @dev returns the `price_` in 1e27, given a `yearlyRatePercent_` yield in percent (1e2 = 1%) and a `timeToMaturity_`.\\n function _priceAtRateToMaturity(\\n uint256 yearlyRatePercent_,\\n uint256 timeToMaturity_\\n ) internal pure returns (uint256 price_) {\\n // formula: x = 100% / (100% + (yearlyRatePercent * timeToMaturity / 1year)\\n // with scaling (100% = 1e20, result scaled to 1e27):\\n // x = 1e20 * 1e27 / (1e20 +(yearlyRatePercent * 1e16 * timeToMaturity / 1year))\\n // e.g. when 100 days to maturity and yield rate is 4%\\n // x = 1e20 * 1e27 / (1e20 + (400 * 1e16 * 100 days /365 days))\\n return\\n (1e20 * (10 ** OracleUtils.RATE_OUTPUT_DECIMALS)) /\\n (1e20 + ((yearlyRatePercent_ * 1e16 * timeToMaturity_) / 365 days));\\n }\\n}\\n\",\"keccak256\":\"0xc6aa166b5bf8ca626d66adebef6075584bb19560b7caf23f50995eb3b1f28a62\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/interfaces/external/IPendleMarketV3.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IPendleMarketV3 {\\n function decimals() external view returns (uint8);\\n\\n function expiry() external view returns (uint256);\\n\\n function increaseObservationsCardinalityNext(uint16 cardinalityNext) external;\\n}\\n\",\"keccak256\":\"0xa684faa0ee458f3bbcf1c2a6cfe7b523331f755daa5042aa8216df02306ecb66\",\"license\":\"MIT\"},\"contracts/oracle/interfaces/external/IPendlePYLpOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IPendlePYLpOracle {\\n function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getYtToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getLpToAssetRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getYtToSyRate(address market, uint32 duration) external view returns (uint256);\\n\\n function getLpToSyRate(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\":\"0x4bab806c834afe152e569446110b6b7341418d80fe30347d399e42fc06b63b56\",\"license\":\"MIT\"},\"contracts/oracle/interfaces/iFluidOracle.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.21;\\n\\ninterface IFluidOracle {\\n /// @dev Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for\\n /// backwards compatibility.\\n function getExchangeRate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates\\n function getExchangeRateOperate() external view returns (uint256 exchangeRate_);\\n\\n /// @notice Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations\\n function getExchangeRateLiquidate() external view returns (uint256 exchangeRate_);\\n}\\n\",\"keccak256\":\"0x410b5f85b64414df35131bbf322261e2a11956d58af3800d8b71b5befb9907d4\",\"license\":\"MIT\"},\"contracts/oracle/libraries/oracleUtils.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\n/// @title Oracle utils library\\n/// @notice implements common utility methods for Fluid Oracles\\nlibrary OracleUtils {\\n /// @dev The scaler for max delta point math (100%)\\n uint256 internal constant HUNDRED_PERCENT_DELTA_SCALER = 10_000;\\n /// @dev output precision of rates\\n uint256 internal constant RATE_OUTPUT_DECIMALS = 27;\\n\\n /// @dev checks if `mainSourceRate_` is within a `maxDeltaPercent_` of `checkSourceRate_`. Returns true if so.\\n function isRateOutsideDelta(\\n uint256 mainSourceRate_,\\n uint256 checkSourceRate_,\\n uint256 maxDeltaPercent_\\n ) internal pure returns (bool) {\\n uint256 offset_ = (checkSourceRate_ * maxDeltaPercent_) / HUNDRED_PERCENT_DELTA_SCALER;\\n return (mainSourceRate_ > (checkSourceRate_ + offset_) || mainSourceRate_ < (checkSourceRate_ - offset_));\\n }\\n}\\n\",\"keccak256\":\"0x968b1a0606875abd523895c5075cf6c34c296919e77b0da7dd952374398e2a4c\",\"license\":\"BUSL-1.1\"},\"contracts/oracle/oracles/pendleOracle.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity 0.8.21;\\n\\nimport { FluidOracle } from \\\"../fluidOracle.sol\\\";\\nimport { IPendleMarketV3 } from \\\"../interfaces/external/IPendleMarketV3.sol\\\";\\nimport { IPendlePYLpOracle } from \\\"../interfaces/external/IPendlePYLpOracle.sol\\\";\\nimport { PendleOracleImpl } from \\\"../implementations/pendleOracleImpl.sol\\\";\\n\\n/// @title PendleOracle\\n/// @notice Gets the exchange rate between Pendle and the underlying asset for the Pendle Market.\\ncontract PendleOracle is FluidOracle, PendleOracleImpl {\\n constructor(\\n IPendlePYLpOracle pendleOracle_,\\n IPendleMarketV3 pendleMarket_,\\n uint32 twapDuration_,\\n uint256 maxExpectedBorrowRate_,\\n uint256 minYieldRate_,\\n uint256 maxYieldRate_,\\n uint8 debtTokenDecimals_\\n )\\n PendleOracleImpl(\\n pendleOracle_,\\n pendleMarket_,\\n twapDuration_,\\n maxExpectedBorrowRate_,\\n minYieldRate_,\\n maxYieldRate_,\\n debtTokenDecimals_\\n )\\n {}\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRateOperate() public view override returns (uint256 exchangeRate_) {\\n return _getPendleExchangeRateOperate();\\n }\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRateLiquidate() external view override returns (uint256 exchangeRate_) {\\n return _getPendleExchangeRateLiquidate();\\n }\\n\\n /// @inheritdoc FluidOracle\\n function getExchangeRate() external view override returns (uint256 exchangeRate_) {\\n return _getPendleExchangeRateOperate();\\n }\\n}\\n\",\"keccak256\":\"0x93afcb37120de7f41ed4182a75ff4126f61790e6ef7293e1ff182f307ce2f3c3\",\"license\":\"BUSL-1.1\"}},\"version\":1}",
"bytecode": "0x6101806040523480156200001257600080fd5b5060405162000f1c38038062000f1c83398101604081905262000035916200039e565b868686868686866001600160a01b03871615806200005a57506001600160a01b038616155b806200006a575063ffffffff8516155b8062000074575083155b8062000081575061753084115b806200008b575082155b8062000098575061271083115b80620000a2575081155b80620000af575061753082115b80620000ba57508183115b80620000c9575060068160ff16105b15620000f15760405163c82fc46560e01b815261eb2960048201526024015b60405180910390fd5b60405162439f4b60e91b81526001600160a01b03878116600483015263ffffffff8716602483015260009182918a169063873e960090604401606060405180830381865afa15801562000148573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200016e91906200043b565b925050915081806200017e575080155b15620001a25760405163c82fc46560e01b815261eb2a6004820152602401620000e8565b5050601260ff16866001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001e8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020e91906200048d565b60ff161415806200029f575060405163abca0eab60e01b81526001600160a01b03878116600483015263ffffffff8716602483015266038d7ea4c68000919089169063abca0eab90604401602060405180830381865afa15801562000277573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200029d9190620004b2565b105b15620002c35760405163c82fc46560e01b815261eb2b6004820152602401620000e8565b6001600160a01b03808816608052861660a0819052604080516370c264df60e11b8152905163e184c9be916004808201926020929091908290030181865afa15801562000314573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200033a9190620004b2565b60c05263ffffffff90941660e05261010092909252610120526101405260ff166101605250620004cc975050505050505050565b6001600160a01b03811681146200038457600080fd5b50565b805160ff811681146200039957600080fd5b919050565b600080600080600080600060e0888a031215620003ba57600080fd5b8751620003c7816200036e565b6020890151909750620003da816200036e565b604089015190965063ffffffff81168114620003f557600080fd5b80955050606088015193506080880151925060a088015191506200041c60c0890162000387565b905092959891949750929550565b805180151581146200039957600080fd5b6000806000606084860312156200045157600080fd5b6200045c846200042a565b9250602084015161ffff811681146200047457600080fd5b915062000484604085016200042a565b90509250925092565b600060208284031215620004a057600080fd5b620004ab8262000387565b9392505050565b600060208284031215620004c557600080fd5b5051919050565b60805160a05160c05160e0516101005161012051610140516101605161098862000594600039600081816101f8015281816103c20152818161065201526106a90152600081816101d701526105780152600081816101b601526105a6015260008181610195015261061a0152600081816101740152818161028c0152610480015260008181610153015281816103560152610384015260008181610132015281816102640152610458015260008181610111015281816102b801526104ac01526109886000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80638e7bfbc014610051578063aafc82701461006c578063e6aa216c14610051578063f3190c89146100e7575b600080fd5b6100596100ef565b6040519081526020015b60405180910390f35b6100746100fe565b6040805173ffffffffffffffffffffffffffffffffffffffff9c8d1681529b909a1660208c0152988a019790975263ffffffff9095166060890152608088019390935260a087019190915260c086015260ff1660e085015261010084015261012083015261014082015261016001610063565b610059610346565b60006100f9610350565b905090565b60008060008060008060008060008060007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061021f610350565b610227610694565b6040517fabca0eab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156102ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103239190610757565b9a509a509a509a509a509a509a509a509a509a509a50909192939495969798999a565b60006100f9610694565b600080427f0000000000000000000000000000000000000000000000000000000000000000116103815760006103a5565b427f0000000000000000000000000000000000000000000000000000000000000000035b905080600003610404576103bb6012600a6108bf565b6103e960ff7f000000000000000000000000000000000000000000000000000000000000000016601b6108ce565b6103f490600a6108e1565b6103fe91906108ed565b91505090565b6104106012601b610928565b61041b90600a6108e1565b6040517fabca0eab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156104f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105179190610757565b610521919061093b565b915061052f601b600a6108e1565b821115610571576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261eb2c60048201526024015b60405180910390fd5b600061059d7f0000000000000000000000000000000000000000000000000000000000000000836106e5565b905060006105cb7f0000000000000000000000000000000000000000000000000000000000000000846106e5565b9050818410806105da57508084115b15610615576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261eb2c6004820152602401610568565b61063f7f0000000000000000000000000000000000000000000000000000000000000000846106e5565b935061064d6012600a6108bf565b6106787f0000000000000000000000000000000000000000000000000000000000000000600a6108bf565b610682908661093b565b61068c91906108ed565b935050505090565b60006106a26012600a6108bf565b6106d060ff7f000000000000000000000000000000000000000000000000000000000000000016601b6108ce565b6106db90600a6108e1565b6100f991906108ed565b60006301e13380826106fe85662386f26fc1000061093b565b610708919061093b565b61071291906108ed565b6107259068056bc75e2d631000006108ce565b610731601b600a6108e1565b6107449068056bc75e2d6310000061093b565b61074e91906108ed565b90505b92915050565b60006020828403121561076957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b808511156107f857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156107de576107de610770565b808516156107eb57918102915b93841c93908002906107a4565b509250929050565b60008261080f57506001610751565b8161081c57506000610751565b8160018114610832576002811461083c57610858565b6001915050610751565b60ff84111561084d5761084d610770565b50506001821b610751565b5060208310610133831016604e8410600b841016171561087b575081810a610751565b610885838361079f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156108b7576108b7610770565b029392505050565b600061074e60ff841683610800565b8082018082111561075157610751610770565b600061074e8383610800565b600082610923577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561075157610751610770565b80820281158282048414176107515761075161077056fea26469706673582212209757c3b74d3ea6ebd21f360d93a8371db9cff77add4036af1fb953b08b5dd5d264736f6c63430008150033",
"deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80638e7bfbc014610051578063aafc82701461006c578063e6aa216c14610051578063f3190c89146100e7575b600080fd5b6100596100ef565b6040519081526020015b60405180910390f35b6100746100fe565b6040805173ffffffffffffffffffffffffffffffffffffffff9c8d1681529b909a1660208c0152988a019790975263ffffffff9095166060890152608088019390935260a087019190915260c086015260ff1660e085015261010084015261012083015261014082015261016001610063565b610059610346565b60006100f9610350565b905090565b60008060008060008060008060008060007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061021f610350565b610227610694565b6040517fabca0eab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156102ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103239190610757565b9a509a509a509a509a509a509a509a509a509a509a50909192939495969798999a565b60006100f9610694565b600080427f0000000000000000000000000000000000000000000000000000000000000000116103815760006103a5565b427f0000000000000000000000000000000000000000000000000000000000000000035b905080600003610404576103bb6012600a6108bf565b6103e960ff7f000000000000000000000000000000000000000000000000000000000000000016601b6108ce565b6103f490600a6108e1565b6103fe91906108ed565b91505090565b6104106012601b610928565b61041b90600a6108e1565b6040517fabca0eab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1660248301527f0000000000000000000000000000000000000000000000000000000000000000169063abca0eab90604401602060405180830381865afa1580156104f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105179190610757565b610521919061093b565b915061052f601b600a6108e1565b821115610571576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261eb2c60048201526024015b60405180910390fd5b600061059d7f0000000000000000000000000000000000000000000000000000000000000000836106e5565b905060006105cb7f0000000000000000000000000000000000000000000000000000000000000000846106e5565b9050818410806105da57508084115b15610615576040517fc82fc46500000000000000000000000000000000000000000000000000000000815261eb2c6004820152602401610568565b61063f7f0000000000000000000000000000000000000000000000000000000000000000846106e5565b935061064d6012600a6108bf565b6106787f0000000000000000000000000000000000000000000000000000000000000000600a6108bf565b610682908661093b565b61068c91906108ed565b935050505090565b60006106a26012600a6108bf565b6106d060ff7f000000000000000000000000000000000000000000000000000000000000000016601b6108ce565b6106db90600a6108e1565b6100f991906108ed565b60006301e13380826106fe85662386f26fc1000061093b565b610708919061093b565b61071291906108ed565b6107259068056bc75e2d631000006108ce565b610731601b600a6108e1565b6107449068056bc75e2d6310000061093b565b61074e91906108ed565b90505b92915050565b60006020828403121561076957600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600181815b808511156107f857817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156107de576107de610770565b808516156107eb57918102915b93841c93908002906107a4565b509250929050565b60008261080f57506001610751565b8161081c57506000610751565b8160018114610832576002811461083c57610858565b6001915050610751565b60ff84111561084d5761084d610770565b50506001821b610751565b5060208310610133831016604e8410600b841016171561087b575081810a610751565b610885838361079f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156108b7576108b7610770565b029392505050565b600061074e60ff841683610800565b8082018082111561075157610751610770565b600061074e8383610800565b600082610923577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561075157610751610770565b80820281158282048414176107515761075161077056fea26469706673582212209757c3b74d3ea6ebd21f360d93a8371db9cff77add4036af1fb953b08b5dd5d264736f6c63430008150033",
"devdoc": {
"kind": "dev",
"methods": {
"getExchangeRate()": {
"details": "Deprecated. Use `getExchangeRateOperate()` and `getExchangeRateLiquidate()` instead. Only implemented for backwards compatibility."
}
},
"title": "PendleOracle",
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {
"getExchangeRateLiquidate()": {
"notice": "Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for liquidations"
},
"getExchangeRateOperate()": {
"notice": "Get the `exchangeRate_` between the underlying asset and the peg asset in 1e27 for operates"
},
"pendleOracleData()": {
"notice": "returns all Pendle oracle related data as utility for easy off-chain use / block explorer in a single view method"
}
},
"notice": "Gets the exchange rate between Pendle and the underlying asset for the Pendle Market.",
"version": 1
},
"storageLayout": {
"storage": [],
"types": null
}
}