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

Inaccurate Calculation of USD Value of Tokens Due to Assumed Decimals Always 18

Summary

getUsdValue function, which calculates the USD value of a given amount of a specific token, assumes that the decimals is always 18. This assumption can lead to incorrect health calculations in the _calculateHealthFactor function, which assumes that the USD value is in 18 decimal places.

Vulnerability Details

For example USDC which is commonly used as collateral in DAI, has 6 decimal places. When getUsdValue is called with 1000 USDC, it returns 1000000000 (calculated as 1e8 * 1e10 * 1000e6 / 1e18).

If the minimum collateral ratio is 200%, you should be able to mint a maximum of 500 DSC. However, if you mint 500 DSC, the health becomes 100000000 (calculated as 1000000000 * 50 * 1e18 / 500e18), which is less than the MIN_HEALTH_FACTOR (1e18), leading to a revert.

Hence, if the token's decimals are less than 18, you can't mint as much DSC as intended, and if it's greater than 18, you can mint more DSC than intended.

Impact

Users may not be able to mint DSC tokens in the amounts they intend

Tools Used

VS Code

Recommendations

I recommend modifying the getUsdValue function as follows:

function getUsdValue(ERC20 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) * 1e18 * amount) / (PRECISION * (10 ** token.decimals()));
}

Support

FAQs

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