# Skipped-path counter and iterator desync

Cleanup, zero-value, or early-return branches that skip a counter decrement or iterator advance

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; one confirmed bounty: $100; latest 2026-06-16. Updated 2026-10-23._

## How it works
A shared counter or iterator is advanced on the normal path but not on a shortcut path. The code assumes every path that consumes a resource also releases it symmetrically. When a branch returns early, handles a zero amount, or tears down state, the matching decrement or advance is skipped, so the counter or index drifts from reality. Later code trusts the stale value.

## Where it shows up
- Teardown/free functions that release queued items without subtracting their accounted cost [E1](https://bugbountylibrary.com/r/h1%3A3701692.md)
- Loops that pull from an iterator only inside a conditional branch (e.g. `if fee > 0`) [E2](https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.10.md)
- Modifiers or gates that inspect a fixed index (index 0) of an array that other routines reorder [E3](https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-01.md)
- Event handlers where a variable is reassigned between two checks and only one result is forwarded [E4](https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AH-01.md)
- Zero-value, empty, or edge-case amounts as the trigger for the skipped branch [E2](https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.10.md)

## How to review
For each counter or iterator, list every path that increments/advances and every path that decrements/releases. The invariant: after any path, the counter equals the sum of live items, and the iterator index stays paired with its parallel array. Check cleanup and error paths explicitly, not just the happy path. For gates on an index, confirm no routine reorders that array. For handlers, trace which variable actually reaches the sink.

## Variants seen
- Teardown frees memory but leaves global byte accounting inflated [E1](https://bugbountylibrary.com/r/h1%3A3701692.md)
- Zero fee skips consuming an account, desyncing iterator from creator array [E2](https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.10.md)
- Repaid position shifted to index 0 makes a gate revert wrongly [E3](https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-01.md)
- Reassignment drops discrepancy events so malicious proposals go unchallenged [E4](https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AH-01.md)

## Impact and severity
Ranged from inflated accounting driving OOM [E1](https://bugbountylibrary.com/r/h1%3A3701692.md), to failed sales [E2](https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.10.md), blocked insolvency declaration [E3](https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-01.md), and unchallenged malicious actions [E4](https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AH-01.md). Severity rises when the stale value gates a security decision (E4) or grows unbounded toward resource exhaustion (E1). Zero-value and edge inputs make it worse because they are easy to trigger.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A3701692.md
- E2: https://bugbountylibrary.com/r/cantina%3Atensor_nov2024%3A3.2.10.md
- E3: https://bugbountylibrary.com/r/c4%3A2022-11-debtdao%3AH-01.md
- E4: https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AH-01.md
