# Disabling outbound transactions is ineffective and allows for Zeta token theft

When outbound transactions are disabled, pending outbound cctxs still get signed and always transfer Zeta tokens regardless of coin type, letting attackers steal Zeta.

- Payout: Contest reward
- Severity: high
- Program: ZetaChain
- Credited: berndartmueller
- Disclosed: 2024-09-06
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-11-zetachain-findings/issues/414
- Library page: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AH-05
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:go technique:source-review vuln:access-control vuln:business-logic

**Target:** EVM signer TryProcessOutTx in zetaclient node
**Root cause:** The IsOutboundEnabled flag is only checked in the branch for cctxs originating from ZetaChain; other pending outbound cctxs fall through to a branch that always signs a Zeta token transfer via onReceive, ignoring the actual coin type.
**Steps:**
1. Disable outbound transactions (flags.IsOutboundEnabled = false).
2. Create a pending outbound cctx with CoinType_ERC20 where the ERC-20 asset is worth less than Zeta (or CoinType_Gas).
3. Observe TryProcessOutTx: the IsOutboundEnabled check at line 452 is skipped, and the else-if at line 530 matches.
4. SignOutboundTx is called with the Zeta connector as `to` and ABI-encoded `onReceive` calldata.
5. The connector's onReceive transfers Zeta tokens to destinationAddress instead of the intended ERC-20/gas asset.
**How found:** Code review of the TryProcessOutTx control flow: noticed the IsOutboundEnabled flag is only checked in one branch, and that the final else-if for PendingOutbound always signs a Zeta transfer regardless of coin type.
**Exploitation:** An attacker initiates a cross-chain outbound with a low-value whitelisted ERC-20 (or gas) while outbound is disabled; the signer still emits a Zeta transfer to the attacker's address, netting the difference between Zeta and the cheap asset.
**Insight:** When a feature flag gates a multi-branch dispatcher, verify the flag is checked before any branch that can still emit a transaction; fall-through branches often ignore both the flag and the intended asset type.
