The function getOraclePrice
may return an incorrect price
Description
The function getOraclePrice
retrieves the latest price for a given pair of assets from a price feed. If there is no corresponding price feed, it will retrieve the price from the inverse price feed and calculate the inverted price.
In the implementation, the decimals of the inverted price are incorrect. The answer
contains AggregatorV3Interface(feed).decimals()
, and the inverted price is expected to have AggregatorV3Interface(feed).decimals()
. But the result of uint256(10 ** AggregatorV3Interface(feed).decimals()) / uint256(answer)
has zero decimals.
function getOraclePrice(address quote, address base) public view returns(uint256) {
bool isInverted = false;
address feed = OracleFeeds(oracleFeeds).priceFeeds(quote, base);
if (feed == address(0)) {
feed = OracleFeeds(oracleFeeds).priceFeeds(base, quote);
// [...]
// Invert the price
isInverted = true;
}
(,int256 answer,,uint256 updatedTimestamp,) = AggregatorV3Interface(feed).latestRoundData();
// [...]
return isInverted ? uint256(10 ** AggregatorV3Interface(feed).decimals()) / uint256(answer) : uint256(answer);
}
Impact
The function getOraclePrice
may return a price lower than the actual value. This will affect other components that depend on it.
Recommendations
Consider making modifications based on the following code.
-return isInverted ? uint256(10 ** AggregatorV3Interface(feed).decimals()) / uint256(answer) : uint256(answer);
+uint256 decimals = uint256(AggregatorV3Interface(feed).decimals());
+return isInverted ? (10 ** decimals * 10 ** decimals) / uint256(answer) : uint256(answer);
Remediation
This issue has been acknowledged by Plaza Finance, and a fix was implemented in commit 7129fa1a↗.