58334 sc medium incorrect function selectors
Submitted on Nov 1st 2025 at 10:49:39 UTC by @teoslaf1 for Audit Comp | Alchemix V3
- Report ID: #58334
- Report Type: Smart Contract
- Report severity: Medium
- Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi\\_audit/src/utils/ZeroXSwapVerifier.sol
- Impacts:
- Contract fails to deliver promised returns, but doesn't lose value
Description
Description
The ZeroXSwapVerifier.sol contract contains hardcoded function selectors that do not match the deployed 0x Settler contract. When legitimate 0x swap calldata is passed for verification, the library immediately reverts because none of the selector checks match the real function signatures.
Although the team stated the verifier is not currently active, it is part of the intended future 0x integration path (for atomic deallocation or direct quote flows). Once integrated, the issue would immediately render the system unable to perform swaps.
Root Cause:
- All 9 function selectors are incorrect and do not match the actual deployed contract.
- The library does not use the canonical 0x deployer (0x00000000000004533Fe15556B1E086BB1A72cEae) to dynamically resolve the latest Settler contract.
- The design hardcodes both selectors and function formats, which are version-specific and subject to change.
Impact:
Wrong selectors: All valid calldata rejected Static Settler assumptions: Breaks on next 0x upgrade No deployer query: Cannot adapt to protocol changes Architectural incompatibility: Future 0x swaps impossible to verify
Recommendation
Update all function selectors to match the deployed 0x Settler contracts. The correct selectors can be obtained by:
- Query the 0x deployer for current Settler address
- Calculate selectors from the actual contract interface
- Verify selectors exist in deployed bytecode
Additional Context (from 0x documentation)
According to the official 0x Settler documentation: https://github.com/0xProject/0x-settler?tab=readme-ov-file#actions
“See ISettlerActions for a list of actions and their parameters. The list of actions, their names, the type and number of arguments, and the availability by chain is NOT STABLE. Do not rely on ABI encoding/decoding of actions directly.”
This means that any implementation hardcoding function selectors or assuming a fixed ABI (as in ZeroXSwapVerifier) is inherently brittle and will break with future Settler updates.
Proof of Concept
Proof of Concept
Manual Verification
Step 1: Find Deployed Contract
cast call 0x00000000000004533Fe15556B1E086BB1A72cEae \
"ownerOf(uint256)(address)" 2 \
--rpc-url https://eth.llamarpc.com
✗ 0x207e1074858A7e78f17002075739eD2745dbaEce
Step 2: Calculate Correct Selector
cast sig "execute((address,address,uint256),bytes[],bytes32)"
✗ 0x1fff991f
Source: https://github.com/0xProject/0x-settler/blob/master/src/interfaces/ISettlerTakerSubmitted.sol
Step 3: Compare
- Correct:
0x1fff991f - ZeroXSwapVerifier has:
0xcf71ff4f - Result: MISMATCH
Step 4: Verify in Bytecode
cast code 0x207e1074858A7e78f17002075739eD2745dbaEce \
--rpc-url https://eth.llamarpc.com | grep -q "1fff991f" && echo "FOUND" || echo "NOT FOUND"
✗ FOUND
cast code 0x207e1074858A7e78f17002075739eD2745dbaEce \
--rpc-url https://eth.llamarpc.com | grep -q "cf71ff4f" && echo "FOUND" || echo "NOT FOUND"
✗ NOT FOUND
For convenience, run the provided verification script:
#!/bin/bash
echo "═══════════════════════════════════════════════════════════"
echo "Simple Verification: ZeroXSwapVerifier Selectors"
echo "═══════════════════════════════════════════════════════════"
echo ""
# Step 1: Get deployed contract
echo "Step 1: Finding deployed 0x Settler contract..."
SETTLER=$(cast call 0x00000000000004533Fe15556B1E086BB1A72cEae "ownerOf(uint256)(address)" 2 --rpc-url https://eth.llamarpc.com 2>/dev/null)
echo " Address: $SETTLER"
echo ""
# Step 2: Get bytecode once
echo "Step 2: Fetching deployed contract bytecode..."
BYTECODE=$(cast code $SETTLER --rpc-url https://eth.llamarpc.com 2>/dev/null)
echo " Bytecode fetched (${#BYTECODE} characters)"
echo ""
# Step 3: Calculate and compare main function selectors
echo "Step 3: Verifying Main Function Selectors"
echo "───────────────────────────────────────────────────────────"
echo ""
echo "execute((address,address,uint256),bytes[],bytes32)"
EXECUTE_CORRECT=$(cast sig "execute((address,address,uint256),bytes[],bytes32)")
echo " Correct: $EXECUTE_CORRECT"
echo " Contract: 0xcf71ff4f"
echo -n " Match: "
if [ "$EXECUTE_CORRECT" = "0xcf71ff4f" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "executeMetaTxn((address,address,uint256),bytes[],bytes32,address,bytes)"
EXECUTE_META_CORRECT=$(cast sig "executeMetaTxn((address,address,uint256),bytes[],bytes32,address,bytes)")
echo " Correct: $EXECUTE_META_CORRECT"
echo " Contract: 0x0476baab"
echo -n " Match: "
if [ "$EXECUTE_META_CORRECT" = "0x0476baab" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
# Step 4: Calculate and compare action selectors
echo "Step 4: Verifying Action Function Selectors"
echo "───────────────────────────────────────────────────────────"
echo ""
echo "BASIC(address,uint256,address,uint256,bytes)"
BASIC_CORRECT=$(cast sig "BASIC(address,uint256,address,uint256,bytes)")
echo " Correct: $BASIC_CORRECT"
echo " Contract: 0x5228831d"
echo -n " Match: "
if [ "$BASIC_CORRECT" = "0x5228831d" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "UNISWAPV3_VIP(address,bytes,(address,uint256,uint256),bytes,uint256)"
UNISWAPV3_CORRECT=$(cast sig "UNISWAPV3_VIP(address,bytes,(address,uint256,uint256),bytes,uint256)")
echo " Correct: $UNISWAPV3_CORRECT"
echo " Contract: 0x9ebf8e8d"
echo -n " Match: "
if [ "$UNISWAPV3_CORRECT" = "0x9ebf8e8d" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "TRANSFER_FROM(address,(address,uint256,uint256),bytes)"
TRANSFER_CORRECT=$(cast sig "TRANSFER_FROM(address,(address,uint256,uint256),bytes)")
echo " Correct: $TRANSFER_CORRECT"
echo " Contract: 0x8d68a156"
echo -n " Match: "
if [ "$TRANSFER_CORRECT" = "0x8d68a156" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "RFQ_VIP(address,(address,uint256,uint256),address,bytes,(address,uint256,uint256),bytes)"
RFQ_CORRECT=$(cast sig "RFQ_VIP(address,(address,uint256,uint256),address,bytes,(address,uint256,uint256),bytes)")
echo " Correct: $RFQ_CORRECT"
echo " Contract: 0x0dfeb419"
echo -n " Match: "
if [ "$RFQ_CORRECT" = "0x0dfeb419" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "VELODROME(address,uint256,address,uint24,uint256)"
VELODROME_CORRECT=$(cast sig "VELODROME(address,uint256,address,uint24,uint256)")
echo " Correct: $VELODROME_CORRECT"
echo " Contract: 0xb8df6d4d"
echo -n " Match: "
if [ "$VELODROME_CORRECT" = "0xb8df6d4d" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "DODOV1(address,uint256,address,bool,uint256)"
DODOV1_CORRECT=$(cast sig "DODOV1(address,uint256,address,bool,uint256)")
echo " Correct: $DODOV1_CORRECT"
echo " Contract: 0x40a07c6c"
echo -n " Match: "
if [ "$DODOV1_CORRECT" = "0x40a07c6c" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
echo "DODOV2(address,address,uint256,address,bool,uint256)"
DODOV2_CORRECT=$(cast sig "DODOV2(address,address,uint256,address,bool,uint256)")
echo " Correct: $DODOV2_CORRECT"
echo " Contract: 0xd92aadfb"
echo -n " Match: "
if [ "$DODOV2_CORRECT" = "0xd92aadfb" ]; then
echo "✅ MATCH"
else
echo "❌ MISMATCH"
fi
echo ""
# Summary
echo "═══════════════════════════════════════════════════════════"
echo "SUMMARY"
echo "═══════════════════════════════════════════════════════════"
echo ""
echo "Main Functions:"
echo " execute: $EXECUTE_CORRECT (Contract has: 0xcf71ff4f) ❌"
echo " executeMetaTxn: $EXECUTE_META_CORRECT (Contract has: 0x0476baab) ❌"
echo ""
echo "Action Functions:"
echo " BASIC: $BASIC_CORRECT (Contract has: 0x5228831d) ❌"
echo " UNISWAPV3_VIP: $UNISWAPV3_CORRECT (Contract has: 0x9ebf8e8d) ❌"
echo " TRANSFER_FROM: $TRANSFER_CORRECT (Contract has: 0x8d68a156) ❌"
echo " RFQ_VIP: $RFQ_CORRECT (Contract has: 0x0dfeb419) ❌"
echo " VELODROME: $VELODROME_CORRECT (Contract has: 0xb8df6d4d) ❌"
echo " DODOV1: $DODOV1_CORRECT (Contract has: 0x40a07c6c) ❌"
echo " DODOV2: $DODOV2_CORRECT (Contract has: 0xd92aadfb) ❌"
echo ""
echo ""
echo "Impact: ZeroXSwapVerifier will reject ALL legitimate 0x swaps"
echo " because it's checking for wrong selectors."
echo ""
chmod +x simple_verify.sh
./simple_verify.sh