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

wBTC Positions Can't Never Be Liquidated

Summary

Due to a Decimal number issue in the getTokenAmountFromUsd() function, it is currently impossible to liquidate wBTC positions. This critical problem poses a significant risk to the protocol's financial stability, potentially leading to insolvency with wBTC holdings becoming worthless.

Vulnerability Details

The liquidate(address collateral, address user, uint256 debtToCover) function relies on getTokenAmountFromUsd(collateral, debtToCover) to calculate the collateral tokens to be redeemed and transferred from the liquidated user to the liquidator.

However, the issue arises due to wBTC having 8 decimal points. The getTokenAmountFromUsd function consistently returns token amounts with 18 decimal points, without considering the specific collateral token that requires liquidation.

When attempting to liquidate a wBTC position, the getTokenAmountFromUsd function returns an inflated amount of wBTC tokens. During the internal _redeemCollateral(user, msg.sender, collateral, totalCollateralToRedeem) process, two critical actions take place:

  1. The liquidated user's wBTC balance in the system is reduced.

  2. The wBTC tokens are transferred to the liquidator user.

Due to an overflow occurring in step 1, the transaction is consistently reverted. This leads to the inability to liquidate unhealthy wBTC positions. As this mechanism is crucial for maintaining the protocol's safety and balance health, the overall safety of the protocol, along with the collateral backing the DSC, could be significantly impacted.

This issue could have been prevented if there were unit tests in place that adequately covered wBTC test cases.
The current commit hash does not include such test cases for wBTC, which might have led to the oversight and subsequent occurrence of the problem.

Impact

The protocol faces the risk of insolvency due to the inability to liquidate wBTC positions. In the event of a substantial drop in wBTC's price, the corresponding collateral's value would significantly decrease, potentially making the protocol insolvent with worthless wBTC holdings.

The following assumption about the system might be broken:
"Our DSC system should always be "overcollateralized". At no point, should the value of all collateral <= the $ backed value of all the DSC"

Tools Used

VSCode

Recommendations

The function getTokenAmountFromUsd needs to account for the token's decimal places when converting USD to the respective token amount. PRECISION needs to be dynamic rather than a constant value. This dynamic approach ensures accurate conversions and adaptability to different token types.

In getTokenAmountFromUsd, change the following line of code:

return (usdAmountInWei * PRECISION) / (uint256(price) * ADDITIONAL_FEED_PRECISION);

to:

return (usdAmountInWei * 10 ** token.decimals()) / (uint256(price) * ADDITIONAL_FEED_PRECISION);

Support

FAQs

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