Lines of code
<https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Oracle.sol#L112-L144>
Oracle contract has 2 functions - viewPrice & getPrice - to get the price through the Chainlink price feed in DOLA. Both functions check the decimals of the feedDecimals answer by calling feed.decimals() and calculate the price by 36 - feedDecimals - tokenDecimals;. DOLA has 18 decimals, hence it can be seen that the feedDecimals is considered not to be higher than 18. If any tokens with decimals higher than 18 are decided to be added to the system and accepted as collateral tokens, both viewPrice & getPrice functions will revert.
For viewPrice;
function viewPrice(address token, uint collateralFactorBps) external view returns (uint) {
if(fixedPrices[token] > 0) return fixedPrices[token];
if(feeds[token].feed != IChainlinkFeed(address(0))) {
// get price from feed
uint price = feeds[token].feed.latestAnswer();
require(price > 0, "Invalid feed price");
// normalize price
uint8 feedDecimals = feeds[token].feed.decimals();
uint8 tokenDecimals = feeds[token].tokenDecimals;
uint8 decimals = 36 - feedDecimals - tokenDecimals; // @audit-info - The function would revert when feedDecimals GT 18
uint normalizedPrice = price * (10 ** decimals);
uint day = block.timestamp / 1 days;
// get today's low
uint todaysLow = dailyLows[token][day];
// get yesterday's low
uint yesterdaysLow = dailyLows[token][day - 1];
// calculate new borrowing power based on collateral factor
uint newBorrowingPower = normalizedPrice * collateralFactorBps / 10000;
uint twoDayLow = todaysLow > yesterdaysLow && yesterdaysLow > 0 ? yesterdaysLow : todaysLow;
if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {
uint dampenedPrice = twoDayLow * 10000 / collateralFactorBps;
return dampenedPrice < normalizedPrice ? dampenedPrice: normalizedPrice;
}
return normalizedPrice;
}
revert("Price not found");
}
For getPrice;
function getPrice(address token, uint collateralFactorBps) external returns (uint) {
if(fixedPrices[token] > 0) return fixedPrices[token];
if(feeds[token].feed != IChainlinkFeed(address(0))) {
// get price from feed
uint price = feeds[token].feed.latestAnswer();
require(price > 0, "Invalid feed price");
// normalize price
uint8 feedDecimals = feeds[token].feed.decimals();
uint8 tokenDecimals = feeds[token].tokenDecimals;
uint8 decimals = 36 - feedDecimals - tokenDecimals; // @audit-info - The function would revert when feedDecimals GT 18
uint normalizedPrice = price * (10 ** decimals);
// potentially store price as today's low
uint day = block.timestamp / 1 days;
uint todaysLow = dailyLows[token][day];
if(todaysLow == 0 || normalizedPrice < todaysLow) {
dailyLows[token][day] = normalizedPrice;
todaysLow = normalizedPrice;
emit RecordDailyLow(token, normalizedPrice);
}
// get yesterday's low
uint yesterdaysLow = dailyLows[token][day - 1];
// calculate new borrowing power based on collateral factor
uint newBorrowingPower = normalizedPrice * collateralFactorBps / 10000;
uint twoDayLow = todaysLow > yesterdaysLow && yesterdaysLow > 0 ? yesterdaysLow : todaysLow;
if(twoDayLow > 0 && newBorrowingPower > twoDayLow) {
uint dampenedPrice = twoDayLow * 10000 / collateralFactorBps;
return dampenedPrice < normalizedPrice ? dampenedPrice: normalizedPrice;
}
return normalizedPrice;
}
revert("Price not found");
}
Manual Review
The team can consider this point if any tokens having more than 18 decimals is decided to be added.
The text was updated successfully, but these errors were encountered:
All reactions