<!-- canonical: https://0xsimao.com/findings/exactly-protocol-update-staking-contract-ii-debt-cleared-accrual-solvency -->

# Some bad debt will not be cleared when it should which will cause accrual of bad debt decreasing the protocol's solvency

Medium · Sherlock · Staking · 22nd July 2024

Finding M-12 of the Exactly Protocol Update - Staking Contract competition.

- Protocol: https://audits.sherlock.xyz/contests/396
- Codebase: https://github.com/0xsimao/2024-07-exactly-stacking-contracts/tree/3eb87e3edf3bcd57c4cc1c6a73e8255f575b76de
- Source: https://github.com/sherlock-audit/2024-07-exactly-stacking-contracts-judging/issues/74

---

### Summary

In `Market::clearBadDebt()`, it only clears bad debt if the `earningsAccumulator` is bigger than the bad debt to clear, but the fixed pool in question may have unassigned earnings which would be added to the earnings accumulator. Thus, the accumulator would have funds to handle the bad debt, but due to checking if it is enough before taking into account its increase, it will not clear the bad debt and will decrease protocol solvency.

### Root Cause

In `Market:641`, it first [checks](https://github.com/sherlock-audit/2024-07-exactly-stacking-contracts/blob/main/protocol/contracts/Market.sol#L641C13-L641C35) if `accumulator >= badDebt` and then in `Market:653` it [increases](https://github.com/sherlock-audit/2024-07-exactly-stacking-contracts/blob/main/protocol/contracts/Market.sol#L653) the accumulator. This should be done in the opposite order as the accumulator may actual be big enough with the added unassigned earnings to clear the bad debt.

### Internal pre-conditions

1. Fixed pool has unassigned earnings.
2. User is liquidated.
3. Accumulator is bigger than the bad debt if it takes into account unassigned earnings.

### External pre-conditions

None.

### Attack Path

1. User borrows maturities but lets them expire and accrues more debt than collateral.
2. User is liquidated, but the accumulator is not enough to cover the bad debt without the unassigned earnings increase, so bad debt keeps accruing.

### Impact

Bad debt accrual which harms protocol users as it increases the risk of insolvency.

### PoC

The following code snippet can be verified to confirm the issue:
```solidity
function clearBadDebt(address borrower) external {
  {
    {
      ...
      if (accumulator >= badDebt) {
        ...
        if (fixedPools[maturity].borrowed == position.principal) {
          earningsAccumulator += fixedPools[maturity].unassignedEarnings;
          fixedPools[maturity].unassignedEarnings = 0;
        }
        ...
      }
    }
  }
  ...
}
```

### Mitigation

Increase the earnings accumulator first and only then compare it against the bad debt.

---

Related findings:

- [Bad debt is never handled which places insolvency risks on BendDAO](https://0xsimao.com/findings/benddao-debt-places-insolvency-risks): BendDAO
- [Most `ManagedLeveragedVault` functions are DoSed due to bad debt check](https://0xsimao.com/findings/beraborrow-i-managed-functions-bad-debt): Beraborrow Managed Dens
- [Profitable liquidations and accumulation of bad debt due to earnings accumulator not being triggered before liquidating](https://0xsimao.com/findings/exactly-protocol-update-staking-contract-liquidations-accumulation-debt-accumulator): Exactly Protocol Update - Staking Contract
- [Expired maturities longer than `FixedLib.INTERVAL` with unaccrued earnings may be arbitraged and/or might lead to significant bad debt creation](https://0xsimao.com/findings/exactly-protocol-update-staking-contract-unaccrued-arbitraged-debt-creation): Exactly Protocol Update - Staking Contract
