15,000 USDC
View results
Submission Details
Severity: high
Valid

If collateral's decimals is not 18, collateral value is not calculated correctly

Summary

If collateral's decimals is not 18, collateral value is not calculated correctly.

Vulnerability Details

Let's examine how collateral value is calculated:

function getAccountCollateralValue(address user) public view returns (uint256 totalCollateralValueInUsd) {
// loop through each collateral token, get the amount they have deposited, and map it to
// the price, to get the USD value
for (uint256 i = 0; i < s_collateralTokens.length; i++) {
address token = s_collateralTokens[i];
uint256 amount = s_collateralDeposited[user][token];
totalCollateralValueInUsd += getUsdValue(token, amount);
}
return totalCollateralValueInUsd;
}

Protocol traverses s_collateralTokens to get the each collateral value:

function getUsdValue(address token, uint256 amount) public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(s_priceFeeds[token]);
(, int256 price,,,) = priceFeed.staleCheckLatestRoundData();
// 1 ETH = $1000
// The returned value from CL will be 1000 * 1e8
return ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION;
}

Collateral value is price * ADDITIONAL_FEED_PRECISION * amount / PRECISION, PRECISION here is 18 because it assumes that every collateral's decimals is 18, however, it's not always the case, collateral with different decimals can be used, for example, USDT has 6 decimals, if USDT is used, its value will be much less than the actual value.

Impact

Collateral's value is not calculated correctly.

Tools Used

Manual Review

Recommendations

The correct way to calculate collateral value should be price * ADDITIONAL_FEED_PRECISION * amount / decimals, where decimals here is the collateral's decimals.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.