# Outbound zEVM cross-chain messages ignore the user-specified gas limit and may fail with an out-of-gas error

zEVM outbound Zeta messages hardcode destination gas to 90000, ignoring the user-specified destinationGasLimit, so onReceive calls can run out of gas and the cctx aborts without refunding the sender.

- 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/406
- Library page: https://bugbountylibrary.com/r/c4%3A2023-11-zetachain%3AM-14
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium technique:source-review vuln:business-logic vuln:dos

**Target:** x/crosschain module ProcessZetaSentEvent / ZetaConnectorZEVM.send
**Root cause:** ProcessZetaSentEvent builds MsgVoteOnObservedInboundTx with a hardcoded gas limit of 90000 instead of the destinationGasLimit supplied in the ZetaSent event's SendInput.
**Steps:**
1. Call `ZetaConnectorZEVM.send(SendInput)` on zEVM with a `destinationGasLimit` larger than 90000 and a destination `onZetaMessage` that needs more than ~100k gas.
2. Observe `PostTxProcessing` -> `ProcessZetaSentEvent` parses the ZetaSent event.
3. Note line 224 passes literal `90000` as the gas limit to `NewMsgVoteOnObservedInboundTx`, discarding `event.DestinationGasLimit`.
4. Observer EVM signer lower-bounds the limit to 100k, so the outbound tx executes with ~100k gas.
5. Destination `onZetaMessage` reverts out-of-gas; cctx is aborted and sender is not refunded.
**How found:** Code review of the zEVM outbound message path: traced ZetaSent event handling in PostTxProcessing/ProcessZetaSentEvent and noticed the gas limit argument was a literal 90000 rather than the event's user-supplied destinationGasLimit.
**Exploitation:** Sender submits a cross-chain message whose destination handler requires more gas than the hardcoded 90k/100k floor; the outbound tx fails with out-of-gas, the cctx is aborted, and the sender loses the funds without refund.
**Insight:** When auditing cross-chain message pipelines, compare the user-supplied gas/limit fields in the emitted event struct against the values actually forwarded into the outbound message constructor; hardcoded literals in the keeper are a common silent override.
