# An attacker can make users unable to cancel their L1 calls on Ethereum To Arbitrum

EthereumToArbitrumRelayer sets Arbitrum retryable ticket callValueRefundAddress to msg.sender (the processor), so the original caller loses the ability to cancel their L1 calls.

- Payout: Audit contest
- Severity: medium
- Program: PoolTogether
- Found by: ktg
- Disclosed: 2023-01-20
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2022-12-pooltogether#m-01
- Library page: http://bugbountylibrary.com/r/c4%3A2022-12-pooltogether%3AM-01
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** EthereumToArbitrumRelayer.sol processCalls / Arbitrum Inbox createRetryableTicket
**Root cause:** createRetryableTicket is called with msg.sender as callValueRefundAddress instead of the original _sender who fingerprinted the calls, so the cancel right is granted to whoever processes the ticket.
**Steps:**
1. User A calls `relayCalls` to fingerprint their calls.
2. User B calls `processCalls` to process user A's calls; inside, `inbox.createRetryableTicket{ value: msg.value }(address(executor), 0, _maxSubmissionCost, msg.sender, msg.sender, _gasLimit, _gasPriceBid, _data)` sets callValueRefundAddress to B.
3. User A cannot cancel the retryable ticket since callValueRefundAddress is B's address.
4. If the call fails, anyone can redeem it and A still cannot cancel.
**How found:** Read Arbitrum Inbox docs noting callValueRefundAddress is the address granted the cancel option, then checked EthereumToArbitrumRelayer's createRetryableTicket call and saw msg.sender (the processor) passed instead of the original sender.
**Exploitation:** Attacker (anyone) calls processCalls on a victim's fingerprinted calls, becoming callValueRefundAddress and thereby holding the sole right to cancel the victim's Arbitrum retryable ticket; the victim loses the cancel option and failed tickets can be redeemed by anyone.
**Insight:** When a relayer wraps a cross-chain messaging primitive, check every address-role parameter (refund/cancel/owner) against who logically should hold that right, not just who is currently executing.

