# `Borrower`'s `modify`, `liquidate` and `warn` functions use stored (outdated) account liabilities which makes it possible for the user to intentionally put him into bad debt in 1 transaction

Aloe Borrower used stale stored borrow balances in health checks, letting a user withdraw into bad debt in one transaction.

- Payout: Contest reward
- Severity: high
- Program: Aloe
- Credited: 0x007
- Disclosed: 2023-10-11
- Write-up quality: 8/10
- Original: https://github.com/sherlock-audit/2023-10-aloe-judging/issues/41
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-10-aloe%3AH-3
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:oracle-manipulation

**Target:** Borrower/Lender lending market contracts
**Root cause:** Borrower._getLiabilities() reads Lender.borrowBalanceStored(), which reflects the balance at the last interest accrual rather than current accrued debt, so health checks in modify/liquidate/warn operate on outdated liabilities.
**Steps:**
1. Borrow max at max leverage plus safety margin (e.g. 10000 DAI borrow, 1051 DAI margin) via `account.modify(this, abi.encode(Action.BORROW, 10000e18, 0), (1<<32))`
2. Wait for market inactivity so accrued interest exceeds the safety margin (e.g. `skip(86400)`; borrowBalance=10630, borrowBalanceStored=10000)
3. Call `account.modify(this, abi.encode(Action.WITHDRAW, 1000e18, 0), (1<<32))`; health check passes against stored 10000 balance though real debt is 10630 > remaining assets
4. Account is now in bad debt but not liquidatable since warn/liquidate also use stored balances; call `lender0.accrueInterest()` then `account.warn((1<<32))`
5. After grace period, liquidate with max strain to avoid swap revert; residual debt remains with zero assets
**How found:** Code reading of Borrower._getLiabilities() noticing it calls borrowBalanceStored instead of borrowBalance (which uses _previewInterest), then reasoning that health checks in modify/liquidate/warn use outdated liabilities.
**Exploitation:** Attacker borrows at max leverage with a safety margin, waits for interest to accrue without settlement, then withdraws collateral sized against the stale stored balance, leaving the account underwater. Optionally deposit large amounts to the lender first so the inflated interest accrues to the attacker's own deposit, making the bad debt profitable at other depositors' expense.
**Escalation:** Deposit large amount to lender before the steps so accrued interest is paid to attacker's deposit while debt goes unpaid, converting bad debt into profit; bad debt can trigger bank run on lender.
**Insight:** When auditing lending markets, check whether health/liquidation math uses stored (last-accrual) balances vs interest-previewed balances; any path that lets a user act before interest settlement can be gamed by waiting for accrual then withdrawing against stale debt.
