# Missing cross-component consistency check

Two components derive the same value independently; check whether anything binds them together

_Area: Smart contract access control and control flow. Seen in 6 disclosed reports; latest 2026-02-26. Updated 2026-10-23._

## How it works
A value, cap, or authorization is computed or enforced in one component, while a second component independently derives or trusts the same value. Nothing asserts the two agree. The broken assumption is that "the other path already checked this" or "both paths compute the same thing." When they diverge, one path's guarantee silently does not hold on the other.

## Where it shows up
- A cap or limit enforced in one function (e.g. close) but not in sibling functions that change the same state (add position, margin) [E2](https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-04.md)
- Two headers/structs carrying the same logical field (fee, hash, amount) validated separately without an equality assertion [E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md)
- A puzzle/layer exit path that builds a coin from an inner hash without asserting that hash [E1](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.5.md)
- Per-item validation (per UserOp, per withdrawal) that ignores other items in the same batch that will also consume the resource [E4](https://bugbountylibrary.com/r/c4%3A2024-03-coinbase%3AM-01.md)
- Fallbacks like `unwrap_or(constant)` that mask a missing comparison [E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md)

## How to review
Identify every value that two components both produce or depend on. The invariant: for each such value, there must be an explicit equality/consistency assertion, or a single source of truth. Check that any cap enforced on one state-changing path is enforced on all paths that reach the same state [E2](https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-04.md). Check that batch validation accounts for the aggregate, not just each item [E4](https://bugbountylibrary.com/r/c4%3A2024-03-coinbase%3AM-01.md). Check that derived hashes/fields are asserted, not assumed [E1](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.5.md)[E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md).

## Variants seen
- Authorization/lineage: exit path omits inner-hash assertion, letting a non-approved layer pass as approved [E1](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.5.md)
- Limit bypass: profit cap missing in an auxiliary position function [E2](https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-04.md)
- Cross-layer field mismatch: consensus vs execution base fee never compared [E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md)
- Batch accounting: per-op balance check ignores sibling ops [E4](https://bugbountylibrary.com/r/c4%3A2024-03-coinbase%3AM-01.md)

## Impact and severity
Led to price-feed control [E1](https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.5.md), excess vault fund extraction [E2](https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-04.md), consensus/execution split [E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md), and postOp reverts/DoS [E4](https://bugbountylibrary.com/r/c4%3A2024-03-coinbase%3AM-01.md). Severity rises when the unbound value gates funds or consensus; batch and fallback patterns make divergence easy to miss in review.

## Why fixes fail
Adding the check to one path while leaving sibling paths or batch aggregation unaddressed leaves the same gap; a constant fallback can hide the missing comparison until divergence occurs [E3](https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md).

## Evidence
- E1: https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.1.5.md
- E2: https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-04.md
- E3: https://bugbountylibrary.com/r/c4%3A2025-09-monad%3AM-07.md
- E4: https://bugbountylibrary.com/r/c4%3A2024-03-coinbase%3AM-01.md
