Skip to content

Latest commit

 

History

History
95 lines (78 loc) · 3.07 KB

023.md

File metadata and controls

95 lines (78 loc) · 3.07 KB

Low Tangerine Cod

High

borrower can create unliquidatable position

Summary

The liquidation refund is sent to the user being liquidated, not to the liquidator.

Root Cause

Whenever admin/liquidator liquidates users. There is a refund happening for updating global variable/chain to the admin/liquidator

    function liquidate(
        address user,
        uint64 index,
        IBorrowing.LiquidationType liquidationType
    ) external payable whenNotPaused(IMultiSign.Functions(2)) onlyAdmin {
...

        // Calling Omnichain send function
        globalVariables.sendForLiquidation{value: fee.nativeFee}(
            IGlobalVariables.FunctionToDo(2),
            noOfLiquidations,
            liquidationInfo,
            getBorrowingResult.depositDetails.assetName,
            fee,
            _options,
->            msg.sender
        );
    }

Core_logic/borrowing.sol#L407

But for the same action in liquidationType1 refund is going to the liquidated user instead of liquidator

    function liquidate(
        address user,
        uint64 index,
        IBorrowing.LiquidationType liquidationType
    ) external payable whenNotPaused(IMultiSign.Functions(2)) onlyAdmin {
...
        CDSInterface.LiquidationInfo memory liquidationInfo = borrowLiquidation
            .liquidateBorrowPosition{value: msg.value - fee.nativeFee}(
-->            user,
            index,
            uint64(ethPrice),
            liquidationType,
            lastCumulativeRate
        );
...
}

    function liquidationType1(
        address user,
        uint64 index,
        uint64 currentEthPrice,
        uint256 lastCumulativeRate
    ) internal returns (CDSInterface.LiquidationInfo memory liquidationInfo) {
...
        if (liqAmountToGetFromOtherChain == 0) {
-->            (bool sent, ) = payable(user).call{value: msg.value}("");
            require(sent, "Failed to send Ether");
        }

    }

borrowLiquidation.sol#L303

Internal pre-conditions

none

External pre-conditions

No response

Attack Path

Create deposit so statement is true - liqAmountToGetFromOtherChain == 0 which almost all the time if borrowers position is not huge with a contract that cannot receive eth. (Exclude receive and fallback Functions)

Impact

Borrower can create unliquidatable deposit/position. System will not be able to get his collateral. liquidation type2 cannot be applied as its still in developments it doesn't work. impact is not a loss of refund which is also true, its more severe

PoC

No response

Mitigation

send to admin refund

        if (liqAmountToGetFromOtherChain == 0) {
-            (bool sent, ) = payable(user).call{value: msg.value}("");
+            (bool sent, ) = payable(admin).call{value: msg.value}("");
            require(sent, "Failed to send Ether");
        }