sherlock-audit / 2024-02-tapioca-judging

2 stars 2 forks source link

cergyk - Market::_computeClosingFactor wrong collateralization calculation can cause liquidatee solvency to become worse #35

Closed sherlock-admin2 closed 7 months ago

sherlock-admin2 commented 7 months ago

cergyk

high

Market::_computeClosingFactor wrong collateralization calculation can cause liquidatee solvency to become worse

Summary

During a market liquidation, a closing factor is computed to ensure that enough of a liquidatee position is closed to make the liquidatee solvent again. However due to a wrong variable used in the calculation, the closing factor is wrongly computed and can lead to the solvency of a liquidatee to become worse after liquidation.

Vulnerability Detail

Let's follow along the calculations made in the function _computeClosingFactor, and see how they impact repaid borrow amount and seized collateral.

First let's eval diff:

collateralizationRate = 0.75
_liquidationMultiplier = 0.12
diff = collateralizationRate*_liquidationMultiplier = 0.84

This gives x (repayable borrow):

_liquidationCollateralizationRate = 0.8
1 / (1 - diff) = 6.25

x = repayableBorrow ~= (totalBorrowAmount - _liquidationCollateralizationRate*collateralInAsset) / (1 - diff) 
= (totalBorrowAmount - 0.8*collateralInAsset) * 6.25

Before liquidation:

let's define X such as:

let X = borrowAmount - 0.8*collateralInAsset 

CollateralOld = Cold
DebtOld = Dold = Cold * 0.8 + X

repayableBorrow = 6.25*X

After liquidation:

liquidationBonus = 1.1

seizedCollateral = repayableBorrow*liquidationBonus = 6.25*1.1*X

CollateralNew = Cnew = Cold - 6.25*1.1*X = Cold - 6.87X
DebtNew = Dnew = Dold - 6.25*X = (Cold * 0.8) + X - 6.25X = Cold*0.8 - 5.25X 

For the account to be solvent after liquidation, we want DNew < 0.8 Cnew:

Dnew < 0.8 Cnew

Cold*0.8 - 5.25X < (Cold - 6.87X) * 0.8 

Cold - 6.56 X < Cold - 6.87 X 

Which is impossible if X > 0

Impact

A position can not be fully liquidated, because closing factor is not big enough. This will leave unhealthy positions unliquidated and cause bad debt to the protocol

Code Snippet

Tool used

Manual Review

Recommendation

Replace collateralizationFactor by _liquidationCollateralizationFactor when computing diff:

- uint256 diff =
-            (collateralizationRate * ((10 ** ratesPrecision) + _liquidationMultiplier)) / (10 ** ratesPrecision);
+ uint256 diff =
+            (_liquidationCollateralizationRate * ((10 ** ratesPrecision) + _liquidationMultiplier)) / (10 ** ratesPrecision);

Duplicate of #53