# KyberSwapDexHooks doesn't check srcReceivers

KyberSwapDexHooks fails to validate SwapDescriptionV2.srcReceivers, letting a guardian redirect part of a vault swap to an arbitrary address and steal tokens.

- Payout: Contest reward
- Severity: medium
- Program: Gauntlet
- Credited: davidjohn
- Disclosed: 2025-08-13
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_gauntlet_jun2025.pdf#3.2.3
- Library page: https://bugbountylibrary.com/r/cantina%3Agauntlet_jun2025%3A3.2.3
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:incomplete-fix technique:source-review vuln:access-control vuln:business-logic

**Target:** KyberSwapDexHooks swap hook / MetaAggregationRouterV2 SwapDescriptionV2
**Root cause:** KyberSwapDexHooks validates the swap but never checks desc.srcReceivers/srcAmounts, while MetaAggregationRouterV2._transferFromOrApproveTarget transfers srcToken from the vault to each srcReceiver.
**Steps:**
1. Guardian crafts a valid Merkle-proven operation calling KYBERSWAP_ROUTER with SWAP_DATA_WETH_USDC.
2. Decode the calldata after the selector into SwapExecutionParams.
3. Append a second srcReceiver `0xabcdef` with srcAmounts[1]=10000 and reduce srcAmounts[0] by 10000.
4. Re-encode selector+params and submit via `vault.submit(Encoder.encodeOperations(ops))` as guardian.
5. Router transfers 10000 WETH to attacker while swap still passes slippage check.
**How found:** Reviewed the swap hook against MetaAggregationRouterV2's _transferFromOrApproveTarget, noticed srcReceivers is attacker-influenced calldata and unchecked by the hook, then modified the existing fork test's swap data to add a malicious receiver.
**Exploitation:** A guardian with a valid Merkle proof for a legitimate swap operation mutates the SwapDescriptionV2 to add an attacker-controlled srcReceiver, so the router splits the vault's srcToken transfer and sends a slice to the attacker; the remaining swap still satisfies slippage checks, hiding the theft.
**Insight:** When a hook whitelists a router call by Merkle proof, audit every field of the router's calldata struct (srcReceivers, dstReceiver, feeReceivers) — a valid proof only pins the selector/target, not the value-routing fields inside.
