# Current implementation of arbitrary call execute failure handler may break some use case for example NFT bridge.

Connext Executor marks transferId used and refunds only ERC20 to recovery address when arbitrary destination call fails, permanently locking bridged NFTs.

- Payout: Audit contest
- Severity: medium
- Program: Connext
- Found by: Chom
- Disclosed: 2022-10-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-06-connext-findings/issues/223
- Library page: https://bugbountylibrary.com/r/c4%3A2022-06-connext%3AM-07
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Executor.sol arbitrary call execution / bridge message handler
**Root cause:** On failed destination call, _handleFailure refunds only the ERC20/native amount to the recovery address and the transferId is marked used, so the original asset (e.g. NFT) is never unlocked and cannot be retried.
**Steps:**
1. Relayer calls execute on BridgeFacet which calls Executor.execute with calldata to unlock NFT on destination chain.
2. Executor computes `gas = gasleft() - FAILURE_GAS` and calls `ExcessivelySafeCall.excessivelySafeCall(_args.to, gas, ...)`.
3. Destination call reverts or runs out of gas (gas spike, frontrun, contract bug), so `success=false`.
4. `_handleFailure` transfers only the ERC20/native amount to `_args.recovery`; NFT remains locked on source chain.
5. transferId is marked used/reconciled, so the message can never be re-executed.
**How found:** Reasoned through the failure path in Executor.execute: noticed _handleFailure only handles ERC20/native refunds and that transferId is consumed regardless of success, then constructed an NFT-bridge scenario where the destination call fails.
**Exploitation:** A relayer (or gas spike / frontrun / destination revert) causes the arbitrary call to fail; the handler refunds only the ERC20 amount to the recovery address and consumes the transferId, leaving the bridged NFT permanently locked on the source chain with no retry path.
**Insight:** When auditing bridge/executor failure handlers, check whether the nonce/transferId is consumed on failure and whether the refund path covers the actual bridged asset class (NFT vs ERC20) — a generic refund to a recovery address silently strands assets that the recovery address cannot represent.

