Little Olive Yeti
High
The expo
value returned by Pyth oracles is related to the decimals of the returned price. Currently, the implementation always assumes expo
is negative. However, if expo
is positive, the protocol will fail to fetch the price correctly.
If expo is positive, then this line will incorrectly calculate the decimals due to overflow.
None needed
- Pyth oracle expo value is positive
As stated in the official Pyth network docs, the expo
value returned from the getPriceUnsafe
function represents the decimal precision of the returned price. This expo
value can be either negative or positive.
If the returned expo
is negative, the following line in PythOracle.sol:151 will get an extra big value because converting negative values to uint will start from the last bit.
The protocol will fail to fetch the price due to unsafe casting from int
to uint
, causing the function to revert due to "0" price. This can be especially problematic during periods of high market activity when price updates are critical. If the admin doesn’t act quickly to change the oracle address, some liquidations may be delayed, potentially resulting in bad debt.
Previous issue found from the same root cause: sherlock-audit/2023-07-perennial-judging#56
If the expo
returned from getPriceUnsafe
is 1
, casting it as uint32(-1)
will result in 2^32 - 1
, which is an extremely large value. Consequently, the scale
will also be a massive number, and the scaledPrice
will evaluate to 0
, causing the price to be incorrectly reported.
uint256 scale = 10 ** (feedDecimals + decimals - PRICE_SCALE);
scaledPrice = price / scale;
No response