# Liquidation will never work with non-zero discounts

MochiVault.liquidate underflows because triggerLiquidation passes undiscounted debt while updateDebt applies a discount, so any non-zero discount profile blocks all liquidations.

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

**Target:** MochiVault / DutchAuctionLiquidator Solidity contracts
**Root cause:** triggerLiquidation computes debt via currentDebt() which does not apply the discount, but the updateDebt modifier subtracts discountedDebt from details[_id].debt; liquidate then does details[_id].debt -= _usdm with the larger undiscounted value.
**Steps:**
1. Configure a discount profile where discount() returns > 0.
2. Call DutchAuctionLiquidator.triggerLiquidation(_nftId, ...) on a position.
3. debt = vault.currentDebt(_nftId) is computed without discount.
4. vault.liquidate(_nftId, collateral, debt) runs updateDebt modifier which sets details[_id].debt = scaledDebt - discountedDebt.
5. Line 293 `details[_id].debt -= _usdm` underflows since _usdm (undiscounted) > details[_id].debt (discounted), reverting.
**How found:** Code reading: noticed currentDebt() does not apply discount while updateDebt subtracts discountedDebt, then traced triggerLiquidation passing the undiscounted value into liquidate's subtraction.
**Insight:** When a value is computed in two places (view helper vs state-updating modifier), diff the formulas line by line; a discount applied in one path but not the other creates an underflow that bricks the whole liquidation flow.
