# Vault fails to track debt correctly that leads to bad debt

MochiVault records total debt using borrow amount instead of amount*1.005, so vault debt undercounts user debt and liquidations revert, leaving bad debt.

- Payout: Audit contest
- Severity: high
- Program: Mochi
- Found by: jonah1005
- Disclosed: 2021-11-23
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-10-mochi-findings/issues/72
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-mochi%3AH-01
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:liquidation

**Target:** MochiVault.sol borrow/repay accounting
**Root cause:** When opening a position the contract increments per-user debt by increasingDebt (_amount*1005/1000) but increments the global debts counter by _amount, so aggregate debt drifts below sum of user debts.
**Steps:**
1. Deposit collateral and call `increase` to borrow max USDM; user debt = amount*1.005 but `debts` += amount.
2. Observe `vault.debts()` is less than sum of `details[_id].debt`.
3. Repay the full `debts()` value plus a bit via `repay(0, repay_amount)`; global debt hits zero while position debt remains.
4. Drop collateral price via `setPrice` and call `triggerLiquidation`; it reverts because `details[_id].debt -= _usdm` underflows / debt already cleared.
**How found:** Compared the borrow path's `increasingDebt` computation against the debt-recording block and noticed `_amount` used instead of `increasingDebt` for `debts` and debtIndex, then traced the consequence through liquidation.
**Exploitation:** Attacker borrows to max, then repays only the undercounted global `debts` amount, zeroing vault debt while retaining an open leveraged position; subsequent liquidations revert, so the position can never be liquidated, leaving the protocol with bad debt when collateral price falls.
**Escalation:** Zeroing global debt disables liquidation for all positions, converting the accounting drift into protocol-wide bad debt.
**Insight:** When a fee is applied to per-user debt, verify the global aggregate and debtIndex use the same post-fee value; a mismatch lets a borrower repay the undercounted global debt to freeze liquidations.
