# Stale state after terminal action

Terminal paths that leave flags, counters, or mappings live, letting the same flow re-trigger or resolve stale

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

## How it works
A terminal action (cancel, expire, settle) is supposed to close an entity for good. The bug is that the action clears only part of the entity's state: a flag, a counter, or one of several mappings stays live. Later code trusts that leftover state, so the closed entity can be re-entered, re-counted, or resolved to old data. The broken assumption is "after a terminal action, nothing about this entity is still actionable."

## Where it shows up
- A cancel/delete path that decrements a shared counter, with no guard preventing the same entity from re-entering it.
- A funding/deposit function with no `isActive`/status check, so a canceled order can be topped up again.
- Status derived from ordered boolean checks where a terminal check (expired) is evaluated before an intermediate one (late).
- Registries with separate ownership and resolution mappings where re-register/expire clears only some of them.
- Getters that rely on an `is_expired` guard which a fresh re-registration silently bypasses.

## How to review
For each terminal action, list every piece of state it should invalidate (flags, counters, mappings, status). Then check each mutation path (cancel, re-fund, re-register, expire, settle) clears all of them, and that no later function can act on the entity without a status guard. For state machines, enumerate every (prior state, new status) pair against the transition table; a higher-priority terminal check must not swallow a needed transition. The invariant: once terminal, an entity is inert — no counter moves, no mapping resolves to it, no flow reopens.

## Variants seen
- Re-funding a canceled order re-triggers delete, repeatedly decrementing a shared counter to zero and underflowing [E1](https://bugbountylibrary.com/r/sherlock%3A2024-10-debita%3AM-6.md).
- Status ordering makes Expired short-circuit Late, so locked capital never unlocks and default detection is skipped [E2](https://bugbountylibrary.com/r/sherlock%3A2023-02-carapace%3AH-4.md).
- Re-registration of an expired domain clears only one mapping, leaving address resolution pointing at the prior owner [E3](https://bugbountylibrary.com/r/c4%3A2025-01-initia-move%3AM-01.md).

## Impact and severity
Medium to high: bricked cancel/match flows [E1](https://bugbountylibrary.com/r/sherlock%3A2024-10-debita%3AM-6.md), locked capital and missed defaults [E2](https://bugbountylibrary.com/r/sherlock%3A2023-02-carapace%3AH-4.md), misdirected transfers to a previous owner [E3](https://bugbountylibrary.com/r/c4%3A2025-01-initia-move%3AM-01.md). Worse when the stale state is shared across entities (a global counter) or when getters hide the staleness behind a guard that a fresh write bypasses.

## Evidence
- E1: https://bugbountylibrary.com/r/sherlock%3A2024-10-debita%3AM-6.md
- E2: https://bugbountylibrary.com/r/sherlock%3A2023-02-carapace%3AH-4.md
- E3: https://bugbountylibrary.com/r/c4%3A2025-01-initia-move%3AM-01.md
