sherlock-audit / 2024-02-leverage-contracts-judging

1 stars 0 forks source link

FastTiger - It can be front-running when the position owner calls the `repay` function to withdraw liquidity in an emergency situation. #21

Closed sherlock-admin closed 8 months ago

sherlock-admin commented 8 months ago

FastTiger

high

It can be front-running when the position owner calls the repay function to withdraw liquidity in an emergency situation.

Summary

Liquidity withdrawal can be prevented by front-running on repay function.

Vulnerability Detail

The owner of the position calls repay function to withdraw his liquidity in an emergency state. However if collateralBalance>=0 repay function is reverted when the owner of the position calls repay function.

collateralBalance is calculated as follows.

function _calculateCollateralBalance(
        uint256 borrowedAmount,
        uint256 borrowingAccLoanRatePerShare,
        uint256 borrowingDailyRateCollateral,
        uint256 accLoanRatePerSeconds
    ) internal pure returns (int256 collateralBalance, uint256 currentFees) {
        if (borrowedAmount > 0) {
            currentFees = FullMath.mulDivRoundingUp(
                borrowedAmount,
                accLoanRatePerSeconds - borrowingAccLoanRatePerShare,
                Constants.BP
            );
89          collateralBalance = int256(borrowingDailyRateCollateral) - int256(currentFees);
        }
    }

Therefore, when the malicious borrower captures the repay function of the position owner in the mempool, it increases the gas cost and calls the increaseCollateralBalance function.

The LiquidityBorrowingManager.sol#increaseCollateralBalance function is as follows.

function increaseCollateralBalance(
        bytes32 borrowingKey,
        uint256 collateralAmt,
        uint256 deadline
    ) external checkDeadline(deadline) {
        BorrowingInfo storage borrowing = borrowingsInfo[borrowingKey];
        // Ensure that the borrowed position exists and the borrower is the message sender
        (borrowing.borrowedAmount == 0 || borrowing.borrower != address(msg.sender)).revertError(
            ErrLib.ErrorCode.INVALID_BORROWING_KEY
        );
        // Increase the daily rate collateral balance by the specified collateral amount
        borrowing.dailyRateCollateralBalance +=
            collateralAmt *
            Constants.COLLATERAL_BALANCE_PRECISION;
        _pay(borrowing.holdToken, msg.sender, VAULT_ADDRESS, collateralAmt);
        emit IncreaseCollateralBalance(msg.sender, borrowingKey, collateralAmt);
    }

As you could see, borrowing.dailyRateCollateralBalance is increased by the increaseCollateralBalance function. Therefore, in the _calculateCollateralBalance function, collateralBalance is set to be greater than 0. As a result, repay function is reverted and the owner of the position may not withdraw his liquidity.

Impact

Position holders cannot withdraw liquidity and may incur losses on his liquidity.

Code Snippet

https://github.com/sherlock-audit/2024-02-leverage-contracts/blob/main/wagmi-leverage/contracts/LiquidityBorrowingManager.sol#L636C9-L671C17 https://github.com/sherlock-audit/2024-02-leverage-contracts/blob/main/wagmi-leverage/contracts/LiquidityBorrowingManager.sol#L611C12-L613C15 https://github.com/RealWagmi/wagmi-leverage/blob/main/contracts/abstract/DailyRateAndCollateral.sol#L77C4-L91C6 https://github.com/sherlock-audit/2024-02-leverage-contracts/blob/main/wagmi-leverage/contracts/LiquidityBorrowingManager.sol#L361C5-L377C6

Tool used

Manual Review

Recommendation

Specify gasLimit for the repay function.

nevillehuang commented 8 months ago

Invalid, insufficient proof and impact described, additionally, I see no issue presented here.