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 a14363c commit 593aba9
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
14 changes: 14 additions & 0 deletions contracts/interfaces/pendle/IPendleTokens.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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);
}
29 changes: 28 additions & 1 deletion contracts/oracles/pendle/PendleTWAPPTPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {WAD, SECONDS_PER_YEAR} from "@gearbox-protocol/core-v3/contracts/librari

import {IPriceFeed} from "@gearbox-protocol/core-v3/contracts/interfaces/base/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 @@ -33,6 +34,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 @@ -52,7 +59,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 @@ -77,6 +86,18 @@ contract PendleTWAPPTPriceFeed is IPriceFeed, PriceFeedValidationTrait, SanityCh
return FixedPoint.divDown(WAD, assetToPTRate);
}

/// @dev Retrieves the current SY and YT indices
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 @@ -85,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 593aba9

Please sign in to comment.