# Same-Asset Borrow Positions Can Become Insolvent With No Working Liquidation Path

K2 allows same-asset collateral/debt borrow positions that become insolvent as debt index outpaces liquidity index, but no liquidation path can clear them.

- Payout: Contest reward
- Severity: high
- Program: K2
- Credited: ChainSentry
- Disclosed: 2026-08-20
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2026-04-k2#h-17
- Library page: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-17
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:rust technique:chained technique:source-review vuln:accounting-error vuln:business-logic vuln:liquidation

**Target:** kinetic-router borrow/liquidation entrypoints (Rust)
**Root cause:** Borrow path never rejects borrowing the same reserve used as collateral, while direct liquidation rejects same-asset pairs and prepared liquidation authorizes them but fails at flash-loan settlement because collateral_to_seize > debt_to_cover drains the same reserve.
**Steps:**
1. Open a borrow position where collateral_asset == debt_asset via the public borrow entrypoint (`operations.rs:285-330`).
2. Wait for debt index to outgrow liquidity index so debt exceeds collateral without price movement.
3. Attempt direct liquidation: rejected as InvalidLiquidation (`validation.rs:517-534`).
4. Call prepare_liquidation: accepted, stores authorization with `debt_to_cover=1_000_000_000`, `collateral_to_seize=1_050_000_000` (`router.rs:510-681`).
5. Call execute_liquidation: flash loan from debt reserve aToken, callback burns same-reserve collateral then returns only debt_to_cover, repayment check fails with `FlashLoanNotRepaid` even with 1:1 swap handler (`flash_loan.rs:387-557`).
**How found:** Compared documented invariant (liquidation docs state collateral and debt assets must differ) against code paths: noticed borrow never enforces the invariant while direct liquidation does, then traced prepare/execute paths and found prepared liquidation authorizes the pair but the same-reserve flash-loan callback burns more collateral than it returns.
**Exploitation:** Any user opens a same-asset collateral/debt position through the public borrow entrypoint; over time the position becomes insolvent. Liquidators cannot clear it: direct liquidation is hard-rejected and prepared liquidation fails at execution, leaving bad debt that only uncompensated third-party repayment can reduce.
**Insight:** When a protocol documents an invariant enforced in one path (liquidation rejects same-asset pairs), check whether the complementary path (borrow/position creation) enforces it too; cross-path invariant mismatches create unliquidatable state. Also trace flash-loan callbacks for same-reserve accounting where seized > repaid.
