# Observer Can Temporarily Halt Chain

Slashing a single observer triggers keygen restart and disables inbound CCTXs, halting the chain until a manual multi-step TSS migration completes.

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

**Target:** observer module BeginBlocker / staking slashing hooks (Cosmos SDK chain)
**Root cause:** BeforeValidatorSlashed removes an observer when delegation drops below MinObserverDelegation, changing observer count; BeginBlocker detects the mismatch and calls DisableInboundOnly plus SetKeygen, halting inbound CCTXs until a manual TSS key migration.
**Steps:**
1. Slash any single observer (e.g. validator goes offline or is slashed) so resultingTokens < MinObserverDelegation.
2. BeforeValidatorSlashed removes the observer from ObserverList, changing totalObserverCountCurrentBlock.
3. BeginBlocker sees count mismatch vs lastBlockObserverCount and executes `k.DisableInboundOnly(ctx)` and `k.SetKeygen(ctx, types.Keygen{BlockNumber: math.MaxInt64})`.
4. Inbound CCTXs are disabled; recovery requires manual TSS keygen voting by all key holders, admin MigrateFSSFunds, updating TSS address on connector/ERC20Custody contracts on all chains, then re-enabling inbound.
**How found:** Code reading of the observer module's BeginBlocker and staking slashing hooks, tracing that observer count changes only on slashing and that a mismatch disables inbound and restarts keygen.
**Exploitation:** A malicious validator or accidental outage causes slashing of one observer, triggering the automatic halt; recovery depends on manual multi-party steps (11 TSS voters plus admin), yielding prolonged downtime.
**Insight:** In Cosmos-style chains, trace automatic slashing hooks into module BeginBlocker/EndBlocker state transitions: a routine slashing event can flip a global liveness flag (inbound disabled) whose recovery path is manual and multi-party, turning a common event into chain-wide downtime.
