# Call to declareInsolvent() would revert when contract status reaches liquidation point after repayment of credit position 1

LineOfCredit.declareInsolvent() reverts because whileBorrowing() checks credits[ids[0]].principal==0 after stepQ shifts a repaid position to index 0, blocking insolvency declaration.

- Payout: Contest reward
- Severity: high
- Program: Debt DAO
- Credited: cryptphi
- Disclosed: 2023-02-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-debtdao-findings/issues/69
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** LineOfCredit.sol declareInsolvent / whileBorrowing modifier
**Root cause:** whileBorrowing() requires credits[ids[0]].principal != 0, but stepQ() in _repay() moves the repaid (zero-principal) position to ids[0], so the modifier reverts even when other positions remain outstanding.
**Steps:**
1. Set up LineOfCredit with 5 lender credit positions.
2. Borrower calls LineOfCredit.borrow() drawing on all 5 position ids.
3. Borrower repays credit position id 1 via _repay(), triggering ids.stepQ() which shifts position 1 to ids[0].
4. Contract status reaches LIQUIDATABLE.
5. Arbiter calls declareInsolvent(); whileBorrowing() checks credits[ids[0]].principal == 0 (true) and reverts.
**How found:** Code reading of the whileBorrowing() modifier and the stepQ() index-shift logic in _repay(), noticing the repaid zero-principal position lands at ids[0].
**Exploitation:** Not an attacker-value extraction; the arbiter cannot declare insolvency, blocking the liquidation/insolvency path when a repaid position sits at ids[0].
**Insight:** When a modifier gates on array index 0, check whether any routine reorders that array (e.g. stepQ moving repaid entries forward) so the gate inspects the wrong element.
