# Unbounded storage growth blocks deposits

Per-call storage append or ID allocation with no expiry, cleanup, or recycling that exhausts a fixed cap

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; one confirmed bounty: $4,000; latest 2026-08-20. Updated 2026-10-24._

## How it works
A contract or node appends state on every action — a map entry, a list element, a new ID — but nothing ever removes or recycles it. The code assumes the store is effectively infinite or that entries will be cleaned up later. When the backing store has a hard ceiling (a fixed-size account, a bitmap width, JVM heap), repeated cheap actions fill it. Once full, the write path panics or crashes, and the failure is permanent because the cleanup path either does not exist or does not free the resource.

## Where it shows up
- A map or list written on each call, keyed by something the caller controls (message ID, peer ID, user), with removal only on a cooperative follow-up event [E1](https://bugbountylibrary.com/r/h1%3A363636.md).
- Per-deposit appends into a fixed-size account (PDA) with no realloc and no cleanup on withdrawal [E2](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-01.md).
- A monotonic ID counter whose delete path retires IDs without recycling, checked against a hard maximum [E3](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-04.md).
- Bitmaps or counters packing N slots into a fixed-width integer, where the allocator and the limit are maintained separately.
- Any `require`/`panic` on a capacity check that has no recovery path.

## How to review
Find every write that grows persistent state. For each, ask: what removes it, and does removal actually free the slot? The invariant to confirm: total live entries can never reach the hard cap through attacker-triggered actions alone, or the cap is unreachable because entries expire, are recycled, or the store can grow. Check that removal does not depend on the same party that added the entry cooperating [E1](https://bugbountylibrary.com/r/h1%3A363636.md). Check that delete paths return IDs/slots to the allocator [E3](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-04.md). Check fixed-size stores for realloc or per-withdrawal cleanup [E2](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-01.md).

## Variants seen
- Peer-controlled key with removal gated on a matching response; no TTL or purge [E1](https://bugbountylibrary.com/r/h1%3A363636.md).
- Fixed-size PDA filled by dust deposits, no realloc, no cleanup on withdraw [E2](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-01.md).
- Non-recycling ID counter against a bitmap ceiling, permanent panic after N markets [E3](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-04.md).

## Impact and severity
Led to node crash (JVM memory exhaustion) [E1](https://bugbountylibrary.com/r/h1%3A363636.md), permanent deposit DoS for under $10 [E2](https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-01.md), and irreversible protocol bricking after 64 markets [E3](https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-04.md). Severity is high because the block is permanent and cheap to trigger; it worsens when the trigger is a low-cost action and no admin recovery exists.

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A363636.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-12-autonolas%3AH-01.md
- E3: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-04.md
