# Liquidation accounting and math bugs

Liquidation paths that trust nominal inputs, skip balance updates, or ignore penalty and accrued interest

_Area: DeFi accounting and math bugs. Seen in 11 disclosed reports; latest 2026-08-20. Updated 2026-10-23._

## How it works
Liquidation code computes what to seize, burn, or credit from inputs it assumes are consistent with the actual state change. The assumption breaks when a transfer is a no-op, a cap silently truncates a value, a penalty or gas term is omitted from one side of the equation, or per-position math is applied where netting is required. The result is a mismatch between what the books say and what actually moved.

## Where it shows up
- Transfer helpers without a `from == to` guard, while sibling functions have one [E1](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-13.md)
- Router derives seized collateral from nominal repay inputs instead of re-reading post-transfer balances [E1](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-13.md)
- Penalty documented but absent from debt reduction, token transfer, or collateral payout [E2](https://bugbountylibrary.com/r/c4%3A2024-07-loopfi%3AH-02.md)
- Loss capped per-position at current balance rather than netting signed pnl across positions [E3](https://bugbountylibrary.com/r/sherlock%3A2023-08-symmetrical%3AH-2.md)
- Downstream function caps a returned amount; upstream still burns/charges the uncapped value [E4](https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AH-01.md)
- System-wide collateral totals updated with some subtraction terms but not all (e.g. gas compensation) [E5](https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.1.7.md)
- Two paths reduce collateral (withdraw vs. leverage change) with different validation [E6](https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-04.md)
- Separate debt buckets mutated in an order that zeroes the bucket gating redemptions [E7](https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.16.md)
- User balance clamped to zero but sibling transfer amount left unclamped [E8](https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.17.md)

## How to review
For each liquidation path, trace every quantity that leaves the contract or updates a total, and confirm it equals the actual balance delta. The invariant: post-liquidation, sum of user balances plus protocol totals equals pre-state minus what was genuinely transferred or burned. Check that self-transfers are rejected or short-circuited, that penalties appear in all three places (debt, transfer, payout), that caps propagate to every consumer, and that per-position caps are applied after netting where the protocol intends netting.

## Variants seen
- Self-liquidation no-op via `from == to` [E1](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-13.md)
- Penalty ignored in collateral payout [E2](https://bugbountylibrary.com/r/c4%3A2024-07-loopfi%3AH-02.md)
- Per-position loss cap making outcome order-dependent [E3](https://bugbountylibrary.com/r/sherlock%3A2023-08-symmetrical%3AH-2.md)
- Upstream burn exceeding downstream capped return [E4](https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AH-01.md)
- Omitted term in system collateral accounting [E5](https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.1.7.md)
- Leverage path missing withdrawal margin check [E6](https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-04.md)
- Debt bucket ordering breaking redemption accounting [E7](https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.16.md)
- Unclamped transfer against clamped balance [E8](https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.17.md)

## Impact and severity
Outcomes range from borrower profit at protocol expense [E2](https://bugbountylibrary.com/r/c4%3A2024-07-loopfi%3AH-02.md) and socialized deficit [E1](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-13.md), to liquidator losses [E4](https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AH-01.md), blocked liquidations [E5](https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.1.7.md), and draining other depositors' collateral [E8](https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.17.md). Severity rises when the bug is repeatable, self-serviceable, or silently corrupts a global solvency metric.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AH-13.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-07-loopfi%3AH-02.md
- E3: https://bugbountylibrary.com/r/sherlock%3A2023-08-symmetrical%3AH-2.md
- E4: https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AH-01.md
- E5: https://bugbountylibrary.com/r/cantina%3Abima_december2024%3A3.1.7.md
- E6: https://bugbountylibrary.com/r/c4%3A2025-08-gte-perps-and-launchpad%3AM-04.md
- E7: https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.16.md
- E8: https://bugbountylibrary.com/r/cantina%3Aalchemix_may2025%3A3.1.17.md
