# Expired transfers will lock user funds on the sending chain

Connext TransactionManager pays cancelling relayer in receivingAssetId on the sending chain, so cancel reverts and expired transfers lock user funds forever.

- Payout: Audit contest
- Severity: high
- Program: Connext
- Found by: 0xRajeev
- Disclosed: 2021-08-30
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-07-connext-findings/issues/47
- Library page: https://bugbountylibrary.com/r/c4%3A2021-07-connext%3AH-04
- Tags: area:web3 domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity vuln:accounting-error vuln:business-logic

**Target:** TransactionManager.sol transferAsset() cancel path
**Root cause:** The cancel path pays the relayer in receivingAssetId on the sending chain, but only sendingAssetId is guaranteed to exist there; if receivingAssetId is absent on the sending chain the cancel transaction reverts.
**Steps:**
1. User initiates a cross-chain transfer relying on a relayer to cancel if it expires.
2. Transfer expires; relayer calls the cancel path in TransactionManager.transferAsset() (L510-517).
3. Cancel pays relayer in `receivingAssetId` on the sending chain instead of `sendingAssetId`.
4. If `receivingAssetId` does not exist on the sending chain, the cancel reverts and funds stay locked.
**How found:** Code review of the cancel path in transferAsset(), noticing the relayer payout uses receivingAssetId on the sending chain where only sendingAssetId is assured valid.
**Exploitation:** Not an attacker-driven exploit; a relayer-dependent user whose transfer expires cannot get it cancelled because the cancel payout references an asset absent on the sending chain, leaving funds locked permanently.
**Insight:** In cross-chain escrow/cancel flows, verify every asset referenced on each chain is guaranteed to exist there; relayer-paid cancel paths that reference the destination asset will revert and strand funds.

