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

Liquidations allow for too much debt to be paid back.

Summary

Liquidations allow for too much debt to be paid back, costing the liquidated user more liquidation fees than neccessary.

Vulnerability Details

The liquidate method in DSCEngine implements the liquidation logic, where the liquidator gets a 10% bonus in received collateral as incentive. This bonus is a liquidation penality to the liquidatee. The issue is that liquidate lets the liquidator pay back more debt than neccessary to bring the user back to a good health factor, loosing them more funds in liquidation penalty than neccessary.

Taking the example from the code comments:

  • A user has a collateral of $140 and debt of $100.

  • The liquidator pays back the full $100 debt, receiving $110 in collateral.

  • The user is left with $30 in collateral and $100 in DSC, totalling $130.

If the method would limit the paying of debt to the required amount, however:

  • A user has a collateral of $140 and debt of $100.

  • The liquidator pays $66.66... in debt and receives $73.33... in collateral.

  • This leaves the user with $66.66... in collateral and $33.33... in debt.

  • The user's health factor is now 200%, which is considered enough by the system.

  • If the user were to pay back all debt and withdraw the collateral, he would receive $66.66... collateral and still have $66.66... in DSC, totalling $133.33..., which is more than in the previous example.

The formula to calculate the required dollar amount to be paid back to exactly reach the minimum health factor is:

amount = (collateral - debt * minHealth) / (bonus - minHealth)

In the above example:

amount = ($140 - $100 * 2) / (1.1 - 2) = 66.66...

Impact

Too much of a user's collateral gets sold off during liquidations, leading to potential loss of funds through liquidation penalties.

Tools Used

None

Recommendations

Implement the above formula to limit the amount of debt that can be paid back during a liquidation (or simply check that the health factor at the end of the method is not above the minimum health factor). Consider adding a small buffer on top so that the user is not immediately liquidatable again during the next minor price move.

Support

FAQs

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