# The Sender of an outbound cctx originating from the zEVM is potentially set to an incorrect sender address resulting in lost assets during a refund

Outbound cctx Sender set to tx.origin instead of the emitting contract, so failed-cctx refunds go to the wrong address and access checks break.

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

**Target:** x/crosschain EVM hooks (PostTxProcessing) and ZetaConnectorZEVM
**Root cause:** ProcessZetaSentEvent and ProcessZRC20WithdrawalEvent set the cctx Sender to emittingContract (tx.origin) rather than the event's zetaTxSenderAddress/from field, so intermediary contracts are not recorded as sender.
**Steps:**
1. Deploy an intermediary contract on zEVM that calls ZetaConnectorZEVM or a ZRC-20 withdrawal.
2. Intermediary emits ZetaSent/Withdrawal; PostTxProcessing parses it in ProcessZetaSentEvent/ProcessZRC20WithdrawalEvent.
3. Observe Sender is set to emittingContract = tx.origin (the EOA signer), not the intermediary contract.
4. Craft a cctx that fails on the destination chain; refund is sent to tx.origin instead of the intermediary.
5. For contract-creation txs, To is nil so Sender is nil, losing refunds entirely.
**How found:** Code review of evm_hooks.go tracing how Sender is populated from emittingContract (tx.origin) and following its use as refund receiver in keeper_cross_chain_tx_vote_outbound_tx.go and as zetaTxSenderAddress in ZetaConnectorEth.onReceive.
**Exploitation:** Attacker routes funds through an intermediary contract, forces the outbound cctx to revert, and the refund is delivered to the EOA signer (attacker) rather than the contract, stealing assets; also breaks ZetaInteractor.isValidMessageCall access protection on receivers.
**Insight:** When a bridge derives a message sender from tx.origin/emittingContract instead of the event's declared sender field, intermediary contracts and contract-creation txs misattribute refunds and break sender-based access control; trace every field used both for refunds and receiver-side auth.
