# Loop bound and pagination errors

Cursor start keys, early breaks, and iteration-vs-produced loop bounds that skip entries or miscount totals

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2025-07-21. Updated 2026-11-01._

## How it works
A loop is trusted to visit every relevant entry or to fill a budget. The assumption that breaks is that the loop's bound, start key, or exit condition matches the actual key distribution or output count. When it does not, entries are silently skipped or totals are miscomputed, and no error is raised.

## Where it shows up
- Cursor pagination over keyed stores where the initial cursor is zero bytes or a fixed default [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md)
- Event-scanning loops with `break`/`return` after the first successful match [E2](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-19.md)
- Loops bounded by input index (`i < max`) where the spec bounds by output length (`len(out) < max`) [E3](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md)
- Branches inside the loop that skip appending (queued, insufficient balance, filtered) [E3](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md)
- Paging helpers that reset `nextKey` to empty and never advance [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md)

## How to review
Check the exact invariant: the loop must visit every entry in the intended range, or produce exactly the intended count. For pagination, confirm the start key is a valid lower bound for the real key distribution and that `nextKey` advances monotonically until exhausted [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md). For scanners, confirm no early exit drops later events in the same transaction [E2](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-19.md). For budgeted loops, confirm the bound counts produced outputs, not iterations, and that every skip branch is accounted for [E3](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md). Write a unit test seeding keys above the first page, a multi-event transaction, and a skip-triggering input.

## Variants seen
- Zero start key over keys all above the limit, returning empty forever [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md)
- Early `break` after first parsed event, dropping later events [E2](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-19.md)
- Iteration-count bound instead of produced-count bound, shrinking output [E3](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md)

## Impact and severity
Led to stale weights never updating [E1](https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md), loss of locked/burned funds from unvoted events [E2](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-19.md), and wrong expected withdrawals causing a consensus chain split [E3](https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md). Severity is high because the failure is silent and only surfaces under specific key or event distributions.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2024-06-allora%3AH-12.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-19.md
- E3: https://bugbountylibrary.com/r/cantina%3Aethereum_pectra_teku%3A3.1.1.md
