Skip to content

Commit

Permalink
fix: add syIndex / pyIndex into price computation
Browse files Browse the repository at this point in the history
  • Loading branch information
Van0k committed Oct 25, 2024
1 parent e235748 commit 044a705
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
16 changes: 16 additions & 0 deletions contracts/interfaces/pendle/IPendleTokens.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2024.
pragma solidity ^0.8.17;

interface IPendleYT {
function doCacheIndexSameBlock() external view returns (bool);

function pyIndexLastUpdatedBlock() external view returns (uint256);

function pyIndexStored() external view returns (uint256);
}

interface IPendleSY {
function exchangeRate() external view returns (uint256);
}
28 changes: 27 additions & 1 deletion contracts/oracles/pendle/PendleTWAPPTPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {PriceFeedType} from "@gearbox-protocol/sdk-gov/contracts/PriceFeedType.s

import {IPriceFeed} from "@gearbox-protocol/core-v2/contracts/interfaces/IPriceFeed.sol";
import {IPendleMarket} from "../../interfaces/pendle/IPendleMarket.sol";
import {IPendleYT, IPendleSY} from "../../interfaces/pendle/IPendleTokens.sol";
import {PriceFeedValidationTrait} from "@gearbox-protocol/core-v3/contracts/traits/PriceFeedValidationTrait.sol";
import {SanityCheckTrait} from "@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol";
import {PriceFeedParams} from "../PriceFeedParams.sol";
Expand All @@ -34,6 +35,12 @@ contract PendleTWAPPTPriceFeed is IPriceFeed, PriceFeedValidationTrait, SanityCh
/// @notice Address of the pendle market where the PT is traded
address public immutable market;

/// @notice Address of the Pendle SY connected to the PT
address public immutable sy;

/// @notice Address of the Pendle YT connected to the YT
address public immutable yt;

/// @notice Timestamp of the market (and PT) expiry
uint256 public immutable expiry;

Expand All @@ -53,7 +60,9 @@ contract PendleTWAPPTPriceFeed is IPriceFeed, PriceFeedValidationTrait, SanityCh
skipCheck = _validatePriceFeed(priceFeed, stalenessPeriod);
twapWindow = _twapWindow;

(, address pt,) = IPendleMarket(_market).readTokens();
address pt;

(sy, pt, yt) = IPendleMarket(_market).readTokens();

string memory ptName = IERC20Metadata(pt).name();

Expand All @@ -78,6 +87,17 @@ contract PendleTWAPPTPriceFeed is IPriceFeed, PriceFeedValidationTrait, SanityCh
return FixedPoint.divDown(WAD, assetToPTRate);
}

function _getSYandPYIndex() internal view returns (uint256 syIndex, uint256 pyIndex) {
syIndex = IPendleSY(sy).exchangeRate();
uint256 pyIndexStored = IPendleYT(yt).pyIndexStored();

if (IPendleYT(yt).doCacheIndexSameBlock() && IPendleYT(yt).pyIndexLastUpdatedBlock() == block.number) {
pyIndex = pyIndexStored;
} else {
pyIndex = syIndex >= pyIndexStored ? syIndex : pyIndexStored;
}
}

/// @notice Returns the USD price of the PT token with 8 decimals
function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {
int256 answer = _getValidatedPrice(priceFeed, stalenessPeriod, skipCheck);
Expand All @@ -86,6 +106,12 @@ contract PendleTWAPPTPriceFeed is IPriceFeed, PriceFeedValidationTrait, SanityCh
answer = int256(FixedPoint.mulDown(uint256(answer), _getPTToAssetRate()));
}

(uint256 syIndex, uint256 pyIndex) = _getSYandPYIndex();

if (syIndex < pyIndex) {
answer = int256(uint256(answer) * syIndex / pyIndex);
}

return (0, answer, 0, 0, 0);
}
}

0 comments on commit 044a705

Please sign in to comment.