# A malicious user can craft valid calldata to call 'packed' version of some of lifi endpoints

ABI calldata collision lets a crafted tx decode as both a packed LiFi endpoint call and a valid BridgeData, bypassing validateTxData to redirect bridged funds to the attacker.

- Payout: Contest reward
- Severity: medium
- Program: Superform Erc1155a
- Credited: cergyk
- Disclosed: 2024-02-13
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_superform_erc1155a_dec2023.pdf#3.2.11
- Library page: https://bugbountylibrary.com/r/cantina%3Asuperform_erc1155a_dec2023%3A3.2.11
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** LiFi bridge integration / validateTxData calldata validation
**Root cause:** Packed LiFi endpoints take static calldata whose first word (transactionId) can be set to a valid offset, so the same bytes decode both as the packed endpoint args and as a dynamic BridgeData struct with a different receiver.
**Steps:**
1. Identify packed endpoints (HopFacetPacked, CBridgeFacetPacked) with static arg shapes like `(bytes32,address,uint64,address,uint256,uint64,uint32)`.
2. Set first word `transactionId = bytes32(uint(0x100))` so it doubles as the offset to a BridgeData struct appended after the packed args.
3. Append `abi.encode(bridgeData)` with a benign receiver that passes validateTxData.
4. Call the packed endpoint with the concatenated calldata; it decodes the real receiver (attacker) while validateTxData sees the benign BridgeData receiver.
5. Bridge completes and funds land at attacker's receiver on destination chain.
**How found:** Noticed packed endpoints use static calldata whose first word is an arbitrary bytes32, and that this word can be repurposed as the ABI offset for a dynamic BridgeData struct, producing a dual-decode collision.
**Exploitation:** Attacker submits crafted calldata to a packed LiFi endpoint; validateTxData decodes a benign BridgeData (different receiver) while the endpoint decodes the attacker's receiver, so bridged liquidity is sent to the attacker on the destination chain, potentially draining DstSwapper liquidity.
**Insight:** When a contract validates calldata by decoding it as one struct but forwards the same bytes to an external endpoint with a different signature, check whether the first word can serve as both a scalar and a dynamic-type offset to create a dual-decode collision.
