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

Hardcoded Liquidation Incentive Causes Failure to Liquidate User's Position Within 100% to 110% Collateral Rate Range

Summary

An edge case scenario where a user's position is between 100% and 110% collateralized, and assuming the liquidator misses the opportunity to liquidate before the collateral price experiences a significant drop, the user's position becomes unliquidatable. This situation poses a risk to the DSC of undercollateralization. The issue arises due to the presence of a hardcoded 10% liquidation incentive, which should ideally be a variable rate, especially when the collateralized factor falls within the range of 100% and 110%.

Vulnerability Details

There is a natspec notice comment in liquidate function that says:

A known bug would be if the protocol were 100% or less collateralized, then we wouldn't be able to incentive the liquidators. For example, if the price of the collateral plummeted before anyone could be liquidated.

This holds true for all DeFi protocols. When the collateral asset is below 100%, liquidation becomes pointless and providing incentives becomes unnecessary. However, there is a crucial but often overlooked scenario that I would like to highlight.

As we are aware, the liquidation incentive stands at 10%. Consequently, liquidation can occur when the collateralization rate falls above 110% but remains under 200%. If the collateralization rate surpasses 200%, it indicates a healthy health factor. On the other hand, if it drops below 110%, the liquidation is reverted due to an underflow issue in the _redeemCollateral function.

As shown below, the totalCollateralToRedeem is 110% of tokenAmountFromDebtCovered. (LIQUIDATION_BONUS = 10, LIQUIDATION_PRECISION = 100)

File: DSCEngine.sol
251: uint256 bonusCollateral = (tokenAmountFromDebtCovered * LIQUIDATION_BONUS) / LIQUIDATION_PRECISION;
252: uint256 totalCollateralToRedeem = tokenAmountFromDebtCovered + bonusCollateral;
253: _redeemCollateral(user, msg.sender, collateral, totalCollateralToRedeem);
254: // We need to burn the DSC
255: _burnDsc(debtToCover, user, msg.sender);

So what happen when the liquidation rate is under 110%, for example 109%? Underflow happen (on line 285), because s_collateralDeposited is less than amountCollateral

File: DSCEngine.sol
282: function _redeemCollateral(address from, address to, address tokenCollateralAddress, uint256 amountCollateral)
283: private
284: {
285: s_collateralDeposited[from][tokenCollateralAddress] -= amountCollateral;
...
291: }

The DSCEngine should allow liquidation happen even user's position is 109% collateral rate. This to prevent under 100% collateral happen. But the current code don't allow that. When the collateralization factor of user position is 109%, no one can liquidate.

Our recommendation here is, to make sure above 100% can still be liquidate to protect DSC. One way to solve this is, not hardcoded the liquidation bonus to 10%, when the collateral rate is between 100% - 110%.

Impact

When collateral factor between 100% and 110% the bad position can not be liquidated, while actually it should, to protect DSC protocol undercollateral. Moreover, in worse case situation, when this bad position failed to liquidate, and it's big and massive, it will make DSC depeg because it's undercollateralized

Tools Used

Manual analysis

Recommendations

Rather than having an upfront incentive calculated for liquidator, it's better to first liquidate the debt, and give the incentive later. Or create a special condition where if the collateral factor is between 100% and 110%, the incentive rate is not 10% but it's the amount left after debt is covered.

Support

FAQs

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