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↗.