15,000 USDC
View results
Submission Details
Severity: medium

`mintDsc()`, `burnDSC()` always reverts for whale accounts as `getUsdValue()` overflows

Summary

The function getUsdValue() overflows if amount param is too high.

Vulnerability Details

Assuming ETH/USD = $2000, and amount=981e53, the return statement which is:

return ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION;, overflows the uint256 limit because the (uint256(price) * ADDITIONAL_FEED_PRECISION) * amount part is above the limit.

Impact

getUsdValue() is used by _revertIfHealthFactorIsBroken() which is in turn used by mintDsc(), burnDsc() and liquidate(). These functions will always revert hence blocking the functionality for the specific user/whale.


Since the amount required is very high, I am setting the severity to medium as it would not occur often.


The same overflow condition can arise in getTokenAmountFromUsd().

Tools Used

Manual verification, forge test.

To test the above, inside DSCEngine.t.sol go to testGetUsdValue() and change

- uint256 ethAmount = 15e18;

to

+ uint256 ethAmount = 981e53;


and run through forge test --match-path test/unit/DSCEngineTest.t.sol --match-test testGetUsdValue -vv.
You will get the following:

Failing tests:
Encountered 1 failing test in test/unit/DSCEngineTest.t.sol:DSCEngineTest
[FAIL. Reason: Arithmetic over/underflow] testGetUsdValue() (gas: 29469)

Recommendations

Keeping the precision of price feed to 8 decimals itself instead of trying to match 18 decimal places could be an approach.

Another way could be to divide first and then multiply. This may result in precision loss though and additional code would be required to check such conditions.

Support

FAQs

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