The check for bad debt in liquidatePosition() does not account for the liquidationDiscount, this allows users to call liquidatePosition() when bad debt has accumulated, leading to huge losses for lenders
Audit: 2024-07-loopfi-findings
Severity: HIGH

# Lines of code

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


# Vulnerability details

## Vulnerability Details

The protocol has 2 liquidation functions:

1. `liquidatePosition()` is for liquidations in normal scenarios (no bad debt accumulated)
2. `liquidatePositionBadDebt()` is only for liquidations when bad debt has accumulated

One definition for bad debt is the state when the liquidator purchases all the collateral BUT does not repay the whole debt amount. It will usually leave lenders at a loss.

When LoopFi accumulates bad debt, it is critical to call the `liquidatePositionBadDebt()` function because it will burn shares from the treasury to prevent fund loss from lenders. The following is from `PoolV3.repayCreditAccount()` function.

`loss == debt - liquidation repayAmount`

```solidity
else if (loss > 0) {
            address treasury_ = treasury;
            uint256 sharesInTreasury = balanceOf(treasury_);
            uint256 sharesToBurn = convertToShares(loss);
            if (sharesToBurn > sharesInTreasury) {
                unchecked {
                    emit IncurUncoveredLoss({
                        creditManager: msg.sender,
                        loss: convertToAssets(sharesToBurn - sharesInTreasury)
                    }); // U:[LP-14D]
                }
                sharesToBurn = sharesInTreasury;
            }
            _burn(treasury_, sharesToBurn); // U:[LP-14C,14D]

```

The `liquidatePosition()` function has the following check to revert if the protocol has accumulated bad debt

```solidity
if (calcTotalDebt(debtData) > wmul(position.collateral, spotPrice_)) revert CDPVault__BadDebt();

```

The issue is that this uses the `spotPrice` instead of the `discountedPrice` which is what the liquidator will use when paying back the loan

This oversight allows the following scenario, assume a 10% `liquidationDiscount`

1. Lender lends 80 WETH to PoolV3
2. Borrower borrows puts down 100 WETH worth of pendle LP tokens. to borrow 80 WETH
3. The pendle LP token price drops, the collateral is now only worth 80 WETH
4. Liquidator will call `liquidatePosition()`, since there is a 10% discount he only needs to repay 72 WETH to collect the whole collateral amount
5. In this state the protocol has taken on bad debt because the repaidAmount < debt , but the liquidator did not call `liquidatePositionBadDebt`

## Proof of Concept

The following POC proves the above scenario

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

```bash
forge test --mt test__POC__LiquidatePositionDoesNotAccountForLiquidationDiscount -vv

```

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

    // Setup the CDPVault
    CDPVault vault = createCDPVault(token, 150 et