# Zero-balance branch skips aggregate update

Early return or zero-amount branch that leaves totals, debt, or claimed amounts unchanged

_Area: DeFi accounting and math bugs. Seen in 2 disclosed reports; latest 2025-06-27. Updated 2026-10-23._

## How it works
An accounting routine has a fast path for the zero case: a `continue`, an early return, or a branch taken when an amount or duration is zero. The fast path updates one piece of state (a per-item balance, a local variable) but skips the aggregate it was supposed to keep in step (a total, a debt, a claimed amount). The two records then disagree, and later code trusts the aggregate.

## Where it shows up
- Loops that build parallel arrays and `continue` before advancing every array in lockstep [E1](https://bugbountylibrary.com/r/c4%3A2024-01-opus%3AH-03.md)
- Balance-delta accounting (`before - after`) where an earlier branch already moved the asset into the contract [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-2.md)
- Integrations that call one withdrawal function while the target toggles between two modes via an admin-set duration [E3](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md)
- Any `if (amount == 0) return;` or `duration == 0` branch that precedes a total-supply, total-debt, or claimed-counter write

## How to review
For each zero/early-exit branch, list every state variable the normal path writes and confirm the branch writes the same set, or that skipping is provably harmless. The invariant: after any call, per-item balances and their aggregate must still sum correctly, and any value measured by delta must not have been moved earlier in the same flow. For integrations, enumerate every branch of the target's mode modifiers and check the caller handles each [E3](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md).

## Variants seen
- Loop `continue` before aggregate array update, misaligning later index writes so debt resets while collateral stays [E1](https://bugbountylibrary.com/r/c4%3A2024-01-opus%3AH-03.md)
- Immediate-redeem branch makes finalize-time delta zero, so claimed amount computes as zero and withdrawals block [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-2.md)
- Strategy hardcodes one withdrawal call that silently returns zero when the cooldown mode is off [E3](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md)

## Impact and severity
Consequences ranged from blocked user withdrawals [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-2.md)[E3](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md) to loss of funds, where a user kept collateral while debt was reset and could withdraw it [E1](https://bugbountylibrary.com/r/c4%3A2024-01-opus%3AH-03.md). Severity rises when the skipped aggregate gates solvency or withdrawal eligibility, and when the zero branch is reachable by ordinary user action rather than rare config.

## Why fixes fail
Mode-toggling integrations regress when only one branch is wired up; the zero path stays untested because tests assume the default duration [E2](https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-2.md)[E3](https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-01-opus%3AH-03.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2025-06-notional-exponent%3AM-2.md
- E3: https://bugbountylibrary.com/r/cantina%3Ajigsaw_june2025%3A3.2.7.md
