sherlock-audit / 2023-04-blueberry-judging

8 stars 5 forks source link

HonorLt - Repay and liquidate race after unpausing #104

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

HonorLt

medium

Repay and liquidate race after unpausing

Summary

The mitigation to prevent liquidations when repayments are disabled is not robust enough.

Vulnerability Detail

In the previous audit, an issue was accepted, that liquidations should not be possible when repayments are disabled: https://github.com/sherlock-audit/2023-02-blueberry-judging/issues/290

The mitigation was adding a check if isRepayAllowed:

    function liquidate(
        uint256 positionId,
        address debtToken,
        uint256 amountCall
    ) external override lock poke(debtToken) {
        if (!isRepayAllowed()) revert Errors.REPAY_NOT_ALLOWED();

However, this mitigation is not entirely correct. Once unpaused, if the position is in a liquidatable state, it will be a race between the repayer and liquidators who will call the corresponding functions (repay or liquidate) first.

Impact

Repayments and liquidations share the same enable flag. Once repayments are allowed, if the user's loan is liquidatable, then liquidators can front-run repayments and take advantage of the current state.

Code Snippet

https://github.com/sherlock-audit/2023-04-blueberry/blob/main/blueberry-core/contracts/BlueBerryBank.sol#L492

Tool used

Manual Review

Recommendation

If repayments were disabled, then after unpausing, I think there should be a gap, a safe period when the borrower first has a choice to repay or abandon the loan.

Duplicate of #117