code-423n4 / 2023-07-tapioca-findings

15 stars 10 forks source link

Incorrect parameter for getCallerReward might return 0 reward despite insolvency #1678

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/Tapioca-DAO/tapioca-bar-audit/blob/2286f80f928f41c8bc189d0657d74ba83286c668/contracts/markets/bigBang/BigBang.sol#L577

Vulnerability details

Impact

The calculation of the caller reward uses an incorrect value. If the exchangeRate remains the same but a lot of interest accrues, then there will be no liquidation reward. Without a liquidation reward borrowing positions will not get liquidated and incur bad debt for the protocol.

Proof of Concept

The function Market._getCallerReward is called in BigBang._liquidateUser like this:

//BigBang
uint256 callerReward = _getCallerReward(
    userBorrowPart[user],
    startTVLInAsset,
    maxTVLInAsset
);

//Market
    function _getCallerReward(
        uint256 borrowed,
        uint256 startTVLInAsset,
        uint256 maxTVLInAsset
    ) internal view returns (uint256) {
        if (borrowed == 0) return 0;
        if (startTVLInAsset == 0) return 0;

        if (borrowed < startTVLInAsset) return 0;

The issue is that userBorrowPart does not describe the actual borrowed value/debt, but just his share of the total debt. The part does not increase over time through accruals (opposed to the elastic value which the part describes).

A simple example:

Tools Used

Manual review

Recommended Mitigation Steps

Use the elastic value (users debt consisting of borrowed amount + interest)

Assessed type

Other

c4-pre-sort commented 1 year ago

minhquanym marked the issue as duplicate of #89

c4-judge commented 1 year ago

dmvt marked the issue as satisfactory