sherlock-audit / 2024-02-tapioca-judging

2 stars 2 forks source link

duc - Liquidation without bad debt doesn't update totalBorrow of market #55

Closed sherlock-admin4 closed 5 months ago

sherlock-admin4 commented 5 months ago

duc

high

Liquidation without bad debt doesn't update totalBorrow of market

Summary

During a liquidation of BigBang or Singularity contract, it doesn't update the totalBorrow although it still updates the borrow storage (userBorrowPart) of user.

Vulnerability Detail

In _liquidateUser() function of BBLiquidation contract, it get liquidated borrow amount and collateral share from _updateBorrowAndCollateralShare, then updatestotalCollateralShare.

function _liquidateUser(
    ...
) private {
    uint256 callerReward = _getCallerReward(user, _exchangeRate);

    (uint256 borrowAmount,, uint256 collateralShare) =
        _updateBorrowAndCollateralShare(user, maxBorrowPart, minLiquidationBonus, _exchangeRate);
    totalCollateralShare = totalCollateralShare > collateralShare ? totalCollateralShare - collateralShare : 0;

    ...

However, during the liquidation, totalBorrow isn't updated even though userBorrowPart was updated in the _updateBorrowAndCollateralShare function (code snippet). It's a serious mistake since totalBorrow is intentionally updated in the liquidateBadDebt() function (code snippet).

The same vulnerability exists in SGLLiquidation.

Impact

This issue results in incorrect totalBorrow for markets, which can become very large and reach borrow cap faster. The calculation of borrowing and undercollateralization will be incorrect, leading to inaccurate market states and unexpected losses for users.

Code Snippet

https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/markets/bigBang/BBLiquidation.sol#L246-L273 https://github.com/sherlock-audit/2024-02-tapioca/blob/main/Tapioca-bar/contracts/markets/bigBang/BBLiquidation.sol#L226-L227

Tool used

Manual Review

Recommendation

Update totalBorrow in _liquidateUser function as the following:

(uint256 borrowAmount,, uint256 collateralShare) =
        _updateBorrowAndCollateralShare(user, maxBorrowPart, minLiquidationBonus, _exchangeRate);
uint256 borrowPart = totalBorrow.toBase(borrowAmount, false);
totalBorrow.elastic -= borrowAmount;
totalBorrow.base -= borrowPart;

Duplicate of #49