# Unliquidatable Bad-Debt via Strategy Negative Yield in Liquidation Routines

Negative strategy yield during liquidation triggers removeCollateral's isSolvent check, reverting liquidation and letting attackers mint unbacked jUSD as unliquidatable bad debt.

- Payout: Contest reward
- Severity: high
- Program: Jigsaw
- Credited: CAUsr
- Disclosed: 2025-08-11
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_jigsaw_june2025.pdf#3.1.5
- Library page: https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.1.5
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:cantina sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:liquidation vuln:oracle-manipulation

**Target:** LiquidationManager / StrategyManager / StablesManager collateral withdrawal path
**Root cause:** StrategyManager.claimInvestment calls StablesManager.removeCollateral on negative yield, which unregisters collateral then asserts isSolvent; during liquidation this solvency check reverts the whole liquidation.
**Steps:**
1. Create holding, invest all collateral via StrategyManager.invest into a strategy that can incur negative yield (volatile collateral like ETH).
2. Wait for a negative yield event on the strategy.
3. Optionally add more collateral to the same strategy to amplify.
4. Borrow jUSD up to max.
5. When collateral depreciates, call liquidationManager.liquidate(user, usdc, jUsd, 0, calldata with strategies) — reverts with `3009` (ERR: USER INSOLVENT) from removeCollateral.
6. Even liquidationManager.liquidateBadDebt reverts with `3009` before any transfers, so position is unliquidatable until yield recovers.
**How found:** Code-reading of the liquidation call stack: LiquidationManager.liquidate → StrategyManager.claimInvestment → StablesManager.removeCollateral; noticed the isSolvent assertion in removeCollateral is inappropriate when invoked mid-liquidation on a negative-yield branch.
**Exploitation:** Attacker deposits collateral, invests in a loss-prone strategy, waits for negative yield, borrows max jUSD. On collateral appreciation they keep trading profit; on depreciation the position cannot be liquidated (both liquidate and liquidateBadDebt revert), so attacker keeps borrowed jUSD and protocol absorbs bad debt distributed to jUSD holders.
**Escalation:** Amplify by adding more collateral to the same strategy post-loss; repeat across holdings to scale unbacked jUSD minting.
**Insight:** When a shared collateral-removal helper enforces a solvency invariant, any caller that legitimately operates on already-insolvent state (liquidation, bad-debt paths) will brick; audit every internal call into invariant-checking functions from privileged flows and test negative-yield/loss branches.
