# Event parsed without verifying emitter

Off-chain watcher trusts event topic or fields without checking emitting contract address or parse safety

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

## How it works
An off-chain observer (bridge relayer, cross-chain client, anticheat peer) watches on-chain logs and decides state from them. It assumes a matching event signature means the event came from the trusted contract. That assumption breaks because any contract invoked during a transaction can emit arbitrary logs with any topic. If the observer matches on topic only, an attacker-controlled contract can forge a trusted event. The same class appears when the observer trusts event *contents*: an unvalidated field that fails to parse can abort the watcher loop.

## Where it shows up
- Log parsing that unpacks by signature/topic and never compares `log.Address` to the known emitter.
- Loops that return on the first matching log, letting a spoofed event shadow the real one.
- Attacker-controlled string/bytes fields (name, symbol, denom) parsed with strict UTF-8 or similar in the watcher.
- Watcher loops that early-return on a parse error before advancing the last-checked block cursor.
- Any contract reachable mid-transaction (receiver, callback, onReceive/onRevert) that can emit logs.

## How to review
The invariant: an observer must only act on a log if `log.Address` equals the expected emitter, and a single malformed or unexpected log must not stop cursor advancement. Check each parse site for an explicit emitter check, not just a topic match. Check whether the match loop can be satisfied by a log from a nested call. Check that every field consumed by the watcher is either validated on-chain or handled without aborting the loop. Confirm parse failures are logged and skipped, with the cursor still moving forward.

## Variants seen
- Spoofed cross-chain event with bogus hash leaves a transfer PendingOutbound and blocks the outbound queue [E1](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-03.md).
- Peer-submitted integrity hashes accepted in any order, letting a peer reflect a legitimate value to hide tampering [E2](https://bugbountylibrary.com/r/h1%3A3559522.md).
- Permissionless token deploy with non-UTF8 symbol makes the Rust parser error and early-return, halting attestations and freezing the bridge [E3](https://bugbountylibrary.com/r/c4%3A2021-08-gravitybridge%3AH-02.md).

## Why fixes fail
E3 shows the failure mode: the parser error path returns before updating the last-checked block, so one bad event permanently stalls the watcher. Fixes that only add validation without fixing cursor advancement leave the DoS open.

## Impact and severity
High: blocked outbound queues [E1](https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-03.md), integrity bypass [E2](https://bugbountylibrary.com/r/h1%3A3559522.md), full bridge freeze [E3](https://bugbountylibrary.com/r/c4%3A2021-08-gravitybridge%3AH-02.md). Severity rises when the forged event is reachable by any permissionless contract and when the watcher halts rather than skipping.

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-03.md
- E2: https://bugbountylibrary.com/r/h1%3A3559522.md
- E3: https://bugbountylibrary.com/r/c4%3A2021-08-gravitybridge%3AH-02.md
