# The outbound transaction tracker only keeps track of a maximum of two different transaction hashes, preventing cctxs from being efficiently confirmed and blocking the outbound transaction queue

ZetaChain's outbound tx tracker caps stored hashes at two, so gas-price-bumped replacement tx hashes are dropped, stalling cctx confirmation and blocking the outbound queue.

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

**Target:** crosschain module AddToOutTxTracker / outbound transaction tracker
**Root cause:** AddToOutTxTracker only appends a new hash when len(tracker.HashList) < 2, discarding further hashes; gas-price bumps each epoch produce new tx hashes that never get tracked.
**Steps:**
1. Observer broadcasts outbound tx and submits `MsgAddToOutTxTracker` with its hash.
2. Gas price is increased each epoch (abci.go), observers rebroadcast a replacement tx with a new hash.
3. New `MsgAddToOutTxTracker` arrives but `len(tracker.HashList) < 2` is false, so the hash is discarded.
4. EVM/BTC `observeOutTx` cannot find the tx by tracked hashes, so the cctx is reprocessed repeatedly.
5. Per-tick outbound cctx limit means other pending cctxs are blocked until manual `AddTxHashToOutTxTracker` with inclusion proof.
**How found:** Code review of AddToOutTxTracker's hash-list append condition combined with the per-epoch gas-price bump logic that regenerates tx hashes, tracing how observeOutTx consumes the tracker.
**Insight:** When a tracker stores identifiers for retryable/replaceable transactions, check for hard caps on stored IDs against the retry/replacement mechanism that mutates those IDs.
