# UniswapV3DexHooks: Incorrect Path Parsing for exactOutput Swaps Leads to Slippage/Accounting Bypass

UniswapV3DexHooks parses exactOutput swap paths in forward order, swapping tokenIn/tokenOut roles and applying slippage and loss checks to the wrong asset.

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

**Target:** UniswapV3DexHooks periphery hook (exactOutput swap handler)
**Root cause:** exactOutput paths are encoded in reverse (tokenOut -> fee -> tokenIn), but the hook extracts tokenIn from the first 20 bytes and tokenOut from the last 20 bytes using the same logic as exactInput.
**Steps:**
1. Note Uniswap V3 exactOutput path encoding: `abi.encodePacked(tokenOut, fee, tokenIn)`.
2. Observe hook code: `tokenIn = address(bytes20(params.path[:20])); tokenOut = address(bytes20(params.path[pathLength-20:]));` used for both swap types.
3. Build path `abi.encodePacked(address(tokenB), FEE_30BPS, address(tokenA))` for swapping A->B exactOutput.
4. Call `hooks.exactOutput(params)` as VAULT and decode return; parsedTokenIn==tokenB, parsedTokenOut==tokenA (reversed).
5. Confirm oracle quotes and slippage/loss checks are keyed on the wrong tokens.
**How found:** Code reading: noticed identical path-parsing logic shared between exactInput and exactOutput handlers, then cross-referenced Uniswap docs showing exactOutput paths are encoded in reverse order.
**Exploitation:** When the guardian executes any exactOutput swap through the vault, slippage protection and loss-limit accounting are evaluated against the reversed token pair, so trades that should be blocked pass and legitimate trades may revert.
**Insight:** When a contract handles both exactInput and exactOutput Uniswap paths, check whether the same slice-based token extraction is reused; exactOutput encodes tokenOut first, so any shared parser silently inverts tokenIn/tokenOut and misdirects oracle/slippage checks.
