# The creation of bad debt (mark-down of Credit) can force other loans in auction to also create bad debt

Auction callDebt snapshots the creditMultiplier, so a mark-down during an auction forces other live loans to only accept phase-2 bids and create cascading bad debt.

- Payout: Contest reward
- Severity: high
- Program: Ethereum Credit Guild
- Credited: JCN
- Disclosed: 2024-02-22
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2023-12-ethereumcreditguild-findings/issues/476
- Library page: https://bugbountylibrary.com/r/c4%3A2023-12-ethereumcreditguild%3AH-03
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:liquidation vuln:oracle-manipulation

**Target:** LendingTerm / AuctionHouse auction debt accounting
**Root cause:** callDebt is snapshotted at call time using the then-current creditMultiplier, but onBid recomputes principal with the current (marked-down) multiplier; if principal > creditFromBidder, onBid reverts unless collateralToBorrower==0, which only holds in auction phase 2.
**Steps:**
1. Open multiple loans in a term (e.g. 4% APR) and let ~2% interest accrue over half a year.
2. Offboard the term via `guild.removeGauge(term)` so loans can be called.
3. Call one loan with `term.call(loanId)` and let the auction expire; `auctionHouse.forgive(loanId)` creates bad debt and marks down creditMultiplier (e.g. 0.96e18).
4. Call the remaining loans with `term.callMany(loanIds)` so their callDebt is snapshotted pre-markdown.
5. Attempt `auctionHouse.bid(loanId)` in phase 1: reverts with `LendingTerm: invalid collateral movement` because recomputed principal > callDebt and collateralToBorrower != 0.
6. Wait until phase 2 (`block.timestamp >= startTime + midPoint`); only then can bids succeed, each producing additional bad debt and further mark-down.
**How found:** Code reading of getLoanDebt vs onBid revealed callDebt is a snapshot while principal is recomputed dynamically; tracing the require(collateralToBorrower==0) branch showed only phase-2 bids survive a mark-down.
**Exploitation:** Attacker/liquidator waits for a mark-down event, then bids at the top of phase 2 on all loans whose callDebt was snapshotted pre-markdown, receiving full collateral at a discount while forcing the protocol to realize additional bad debt on each auction.
**Escalation:** Each forced bad-debt auction further reduces creditMultiplier, cascading losses across all terms with live auctions and amplifying protocol insolvency.
**Insight:** When a protocol stores a debt snapshot at auction start but recomputes principal at bid time using a mutable global multiplier, check every branch that compares the two — the mismatch can gate which auction phases are biddable and silently force losses.
