# AddBlockHeader Cannot Cope with Reorgs

ZetaChain's AddBlockHeader only accepts height = latest+1 and no message-server path exists to remove/reorg headers, so a chain reorg beyond confirmations halts observer consensus and breaks trustless proofs.

- Payout: Contest reward
- Severity: medium
- Program: ZetaChain
- Credited: ciphermarco
- Disclosed: 2024-09-06
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-11-zetachain-findings/issues/542
- Library page: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-04
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:code4rena sev:medium tech:go technique:source-review vuln:business-logic vuln:dos

**Target:** Cosmos SDK observer module message server (AddBlockHeader/RemoveBlockHeader)
**Root cause:** AddBlockHeader enforces msg.Height == bhs.LatestHeight+1, and the only removal keeper (RemoveBlockHeader) is never exposed via a message server, so there is no consensus path to replace or delete an already-stored header after a reorg.
**Steps:**
1. Observers reach confirmation threshold (2 BTC, 14 ETH, 14 BSC) and call `AddBlockHeader` for height N, storing the header.
2. A reorg past those confirmations replaces the block at height N with a different hash.
3. Observers attempt to vote in the new header for height N via `AddBlockHeader`.
4. Check `if msg.Height != bhs.LatestHeight+1` fails since LatestHeight is already N, returning `ErrNoParentHash`.
5. No message-server route exists to invoke `RemoveBlockHeader`/`SetBlockHeader`, so the stale header cannot be deleted or overwritten.
**How found:** Code review of the observer module: noticed RemoveBlockHeader keeper exists but is unused anywhere, then traced AddBlockHeader's height check to confirm no reorg remediation path is reachable through the message server.
**Insight:** When auditing consensus/observer modules, check whether state-mutating keeper functions (delete/overwrite) are actually wired to a message server — an unused Remove* keeper plus a strict monotonic height check means the protocol cannot recover from legitimate chain reorganizations.
