# Unverified observer message accepted without proof

Observer or relay messages that change state before proof, signature, or multi-party tally is verified

_Area: Smart contract access control and control flow. Seen in 2 disclosed reports; latest 2024-09-06. Updated 2026-10-25._

## How it works
A cross-chain system trusts a set of observers or relays to report what happened on another chain. The safe assumption is that a report is only acted on after it is proven: a Merkle proof, a signature set, or a quorum tally. The weakness is that a handler checks only *who* sent the message (is this an authorized observer?) and then writes state directly. The *what* — that the reported transaction or nonce is real and agreed — is never established. One authorized sender's claim becomes chain state.

## Where it shows up
- Message handlers that call a setter (nonce, tracker, settlement status) right after an authorization check, with no proof or tally step in between.
- Voting/tally logic commented out, deprecated, or bypassed, while the handler stays reachable.
- Tracker or vote messages (`AddToInTxTracker`, `AddToOutTxTracker`) accepted without Merkle proof verification [E3](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-15.md).
- Nonce setters where a single observer overwrites the chain nonce [E1](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-01.md)[E3](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-15.md).
- Permissionless retry/replay functions that write a terminal status (e.g. Success) for any caller [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-03.md).

## How to review
For each observer/relay entry point, trace from the handler to the state write. The invariant: no externally reported fact (tx existence, nonce, settlement outcome) may reach persistent state unless a proof, signature quorum, or multi-party tally has been verified in the same call path. Check that deprecated handlers are unreachable, that tally code is live and not commented out, and that downstream equality checks (e.g. nonce match in `UpdateNonce`) cannot be driven by one sender. For retry paths, confirm a no-op or zero-cost call cannot flip state to a terminal value that blocks the legitimate owner [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-03.md).

## Variants seen
- Deprecated NonceVoter with voting commented out; one observer sets any chain nonce, desyncing `UpdateNonce` and halting cross-chain operations [E1](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-01.md).
- Tracker messages accepted without Merkle proof, letting one observer forge deposits or halt outbound cctxs [E3](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-15.md).
- Permissionless `retrySettlement` with zero remote gas marks settlement Success, DoSing the owner's `redeemSettlement` and locking assets [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-03.md).

## Impact and severity
High: chain halt and desync [E1](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-01.md), forged deposits and fund drain or halted cross-chain transfers [E3](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-15.md), locked user assets via settlement DoS [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-03.md). Severity rises when a single observer suffices and the write is terminal or feeds an equality check other logic depends on.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-01.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-03.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-15.md
