sherlock-audit / 2023-07-blueberry-judging

2 stars 1 forks source link

0xMosh - Malicious borrower can self liquidate and eventually steal funds . #140

Closed sherlock-admin2 closed 1 year ago

sherlock-admin2 commented 1 year ago

0xMosh

high

Malicious borrower can self liquidate and eventually steal funds .

Summary

Malicious borrower can self liquidate and eventually steal funds . The liquidate function allows anyone to liquidate a bad debt . If an Malicious borrower can use this as attack to borrow first and then liquidate to get the collateral back and eventually leaving the protocol with loss of funds .

Vulnerability Detail

See summary .

Impact

Loss of funds

Code Snippet

Affected code here: https://github.com/sherlock-audit/2023-07-blueberry/blob/main/blueberry-core/contracts/BlueBerryBank.sol#L544 The liquidation function looks like this :

 function liquidate(
        uint256 positionId,
        address debtToken,
        uint256 amountCall
    ) external override lock poke(debtToken) {
        /// Ensures repayments are allowed at the moment of calling this function.
        if (!isRepayAllowed()) revert Errors.REPAY_NOT_ALLOWED();
        /// Ensures a non-zero repayment amount is specified.
        if (amountCall == 0) revert Errors.ZERO_AMOUNT();
        /// Ensures the position is liquidatable.
        if (!isLiquidatable(positionId))
            revert Errors.NOT_LIQUIDATABLE(positionId);

        /// Retrieve the position and associated bank data.
        Position storage pos = positions[positionId];
        Bank memory bank = banks[pos.underlyingToken];
        /// Ensure the position has valid collateral.
        if (pos.collToken == address(0))
            revert Errors.BAD_COLLATERAL(positionId);

        /// Revert liquidation if the repayment hasn't been warmed up 
        /// following the last state where repayments were paused.
        if (
            block.timestamp <
            repayResumedTimestamp + Constants.LIQUIDATION_REPAY_WARM_UP_PERIOD
        ) revert Errors.REPAY_ALLOW_NOT_WARMED_UP();

        /// Repay the debt and get details of repayment.
        uint256 oldShare = pos.debtShare;
        (uint256 amountPaid, uint256 share) = _repay(
            positionId,
            debtToken,
            amountCall
        );

        /// Calculate the size of collateral and underlying vault share that the liquidator will get.
        uint256 liqSize = (pos.collateralSize * share) / oldShare;
        uint256 uVaultShare = (pos.underlyingVaultShare * share) / oldShare;

        /// Adjust the position's debt and collateral after liquidation.
        pos.collateralSize -= liqSize;
        pos.underlyingVaultShare -= uVaultShare;

        /// Transfer the liquidated collateral (Wrapped LP Tokens) to the liquidator.
        IERC1155Upgradeable(pos.collToken).safeTransferFrom(
            address(this),
            msg.sender,
            pos.collId,
            liqSize,
            ""
        );
        /// Transfer underlying collaterals(vault share tokens) to liquidator
        if (_isSoftVault(pos.underlyingToken)) {
            IERC20Upgradeable(bank.softVault).safeTransfer(
                msg.sender,
                uVaultShare
            );
        } else {
            IERC1155Upgradeable(bank.hardVault).safeTransferFrom(
                address(this),
                msg.sender,
                uint256(uint160(pos.underlyingToken)), //@n it is used as an id when transferring an erc1155
                uVaultShare,
                ""
            );
        } 

Tool used

Manual Review

Recommendation

check & Revert if liquidator is the borrower .

sherlock-admin2 commented 1 year ago

2 comment(s) were left on this issue during the judging contest.

0xyPhilic commented:

invalid because the malicious user has no incentive to borrow and self-liquidate after that as he'll pay fees on those operations

Kral01 commented:

Needs PoC