The PendlePTOracle contract may return a wrong price when calculating the price with getPtToAssetRate()
Summary
PendlePTOracle may return a wrong price after expiry, which is hardcoded to 1, if the Pendle oracle function getPtToAssetRate() is used before expiry.
Vulnerability Detail
Note: The term "after expiry" refers to line 115 inside PendlePTOracle.sol where expiry is checked. If expiry <= block.timestamp, it is "after expiry", otherwise it is not expired.
On line 86 inside PendlePTOracle.sol the flag useSyOracleRate is checked, and if it's false the function getPtToAssetRate() is used which may not always guaranteed to be 1:1 price. However, after expiry the protocol always returns a hardcoded price of 1 which is correct for PT-SY pair, but may be wrong for PT-Asset prices which may not be a 1:1 price.
Example:
Before expiry Deployments.PENDLE_ORACLE.getPtToAssetRate (line 88 PendlePTOracle.sol) may return a PT-Asset price which is higher or smaller than 1. So based on that price, for 100e18 PT tokens we may receive 150e18 assets tokens.
After expiry the PT oracle price is hardcoded to 1 (line 113-118 PendlePTOracle.sol), so now for 100e18 PT tokens we receive 100e18 assets.
The example shows that it may be not safe to hardcode the price to 1 for the case where getPtToAssetRate() is used.
A wrong oracle price may be returned after expiry in the case where the price is determined by using getPtToAssetRate(). This may result in a loss for the protocol or for the users.
lemonmon
Medium
The
PendlePTOracle
contract may return a wrong price when calculating the price withgetPtToAssetRate()
Summary
PendlePTOracle
may return a wrong price after expiry, which is hardcoded to 1, if the Pendle oracle functiongetPtToAssetRate()
is used before expiry.Vulnerability Detail
Note: The term "after expiry" refers to line 115 inside PendlePTOracle.sol where
expiry
is checked. Ifexpiry <= block.timestamp
, it is "after expiry", otherwise it is not expired.On line 86 inside PendlePTOracle.sol the flag
useSyOracleRate
is checked, and if it'sfalse
the functiongetPtToAssetRate()
is used which may not always guaranteed to be 1:1 price. However, after expiry the protocol always returns a hardcoded price of 1 which is correct for PT-SY pair, but may be wrong for PT-Asset prices which may not be a 1:1 price.Example:
Before expiry
Deployments.PENDLE_ORACLE.getPtToAssetRate
(line 88 PendlePTOracle.sol) may return a PT-Asset price which is higher or smaller than 1. So based on that price, for 100e18 PT tokens we may receive 150e18 assets tokens.After expiry the PT oracle price is hardcoded to 1 (line 113-118 PendlePTOracle.sol), so now for 100e18 PT tokens we receive 100e18 assets.
The example shows that it may be not safe to hardcode the price to 1 for the case where
getPtToAssetRate()
is used.Reference:
https://docs.pendle.finance/Developers/Contracts/StandardizedYield
https://docs.pendle.finance/Developers/Oracles/HowToIntegratePtAndLpOracle
Impact
A wrong oracle price may be returned after expiry in the case where the price is determined by using
getPtToAssetRate()
. This may result in a loss for the protocol or for the users.Code Snippet
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/14d3eaf0445c251c52c86ce88a84a3f5b9dfad94/leveraged-vaults-private/contracts/oracles/PendlePTOracle.sol#L115
https://github.com/sherlock-audit/2024-06-leveraged-vaults/blob/14d3eaf0445c251c52c86ce88a84a3f5b9dfad94/leveraged-vaults-private/contracts/oracles/PendlePTOracle.sol#L85-L90
Tool used
Manual Review
Recommendation
Consider not using a hardcoded price of 1 for the case where the function
getPtToAssetRate()
is used.Duplicate of #69