# Missing solvency check on position change

Borrow, withdraw, or dust-deposit paths that skip or bypass the health-factor check after a position changes

_Area: DeFi oracles, liquidations and flash loans. Seen in 3 disclosed reports; latest 2025-10-20. Updated 2026-11-02._

## How it works
A lending or margin protocol assumes every state-changing action leaves each account solvent: collateral value must cover debt times a threshold. The check is usually wired into one entry point (borrow, withdraw, open position). When a second path changes the same position — a router that opens a leveraged long, a `cook()`-style multicall with a repay/no-op action, a deposit that is accepted as collateral — the code trusts that the earlier check still holds. It does not re-run the health-factor math after the change. The invariant "post-state is solvent" is never enforced, so an account can end a transaction with debt it cannot cover, or collateral it has already pulled out.

## Where it shows up
- Router or helper contracts (`increaseLongPosition`, `decreaseLongPosition`, `TradeRouter`) that mutate collateral and debt outside the core pool's checked functions.
- Multicall/`cook()` dispatchers where one action (REPAY, NO_OP) is assumed to leave solvency intact and skips the check.
- Withdraw paths that release collateral while a leveraged position stays open.
- Aave-fork `borrow` loops over reserves where the health-factor gate is computed from a deposit that was never properly valued.
- Dust deposits (1 wei / 1e18) accepted as sufficient collateral.

## How to review
Find every function that changes collateral, debt, or both, and confirm each one ends by recomputing the account's health factor against the *post-change* state — not a cached or pre-change value. The property: for every reachable end-state of any transaction, `collateralValue * threshold >= debtValue`. Trace multicall actions individually and in combination; a REPAY or NO_OP branch must still fall through to the solvency check. For forks, verify the borrow limit is derived from the depositor's actual valued collateral, not a BentoBox balance or a token count. Test a dust deposit followed by a max borrow across all reserves.

## How finders spotted it
- [E3](https://bugbountylibrary.com/r/dhl%3A20241119-polterfinance-exploit.md) The finder tested whether a minimal SpookyToken deposit passed the health-factor check and unlocked borrowing the full aToken balance of every reserve — a dust-collateral probe on an Aave fork.
- [E1](https://bugbountylibrary.com/r/dhl%3A20251020-sharwafinance.md) The finder noticed a router let you open a leveraged position and separately withdraw supplied collateral, then asked whether solvency is re-validated after each action.
- [E2](https://bugbountylibrary.com/r/dhl%3A20251004-mimspell3.md) The finder examined `cook()` with a REPAY action and checked whether borrowLimit vs BentoBox balance gating let the full pool balance be borrowed with no collateral.

## Variants seen
- [E1](https://bugbountylibrary.com/r/dhl%3A20251020-sharwafinance.md) Router opens a long and withdraws collateral in one tx; solvency never rechecked, profit taken via flash-loan price manipulation on close.
- [E2](https://bugbountylibrary.com/r/dhl%3A20251004-mimspell3.md) `cook()` REPAY action bypasses solvency, borrowing MIM against no collateral; looped across six cauldrons.
- [E3](https://bugbountylibrary.com/r/dhl%3A20241119-polterfinance-exploit.md) 1 wei collateral deposit unlocks borrowing every reserve's full liquidity in a single transaction.

## Impact and severity
Full reserve drain in each case: ~$7M [E3](https://bugbountylibrary.com/r/dhl%3A20241119-polterfinance-exploit.md), 1.7M USD [E2](https://bugbountylibrary.com/r/dhl%3A20251004-mimspell3.md), and TradeRouter funds drained [E1](https://bugbountylibrary.com/r/dhl%3A20251020-sharwafinance.md). Impact scales with how many reserves or cauldrons a single unchecked position can reach [E2](https://bugbountylibrary.com/r/dhl%3A20251004-mimspell3.md)[E3](https://bugbountylibrary.com/r/dhl%3A20241119-polterfinance-exploit.md), and is amplified when combined with flash-loan price manipulation to realize the profit [E1](https://bugbountylibrary.com/r/dhl%3A20251020-sharwafinance.md).

## Evidence
- E1: https://bugbountylibrary.com/r/dhl%3A20251020-sharwafinance.md
- E2: https://bugbountylibrary.com/r/dhl%3A20251004-mimspell3.md
- E3: https://bugbountylibrary.com/r/dhl%3A20241119-polterfinance-exploit.md
