58743 sc low zeroxswapverifier recipient validation bypass

Submitted on Nov 4th 2025 at 11:20:56 UTC by @teoslaf1 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58743

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/utils/ZeroXSwapVerifier.sol

  • Impacts:

    • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

Description

Summary

The ZeroXSwapVerifier library fails to validate recipient addresses in swap calldata. Despite accepting an owner parameter intended for validation, the library never checks if the recipient in the calldata matches the expected owner. This allows calldata with arbitrary recipient addresses to pass verification, enabling direct fund theft when the library is integrated according to its intended usage pattern.

Vulnerability Details

The library's main verification function accepts an owner parameter:

function verifySwapCalldata(
    bytes calldata calldata_,
    address owner,              // ← Intended to validate ownership
    address targetToken,
    uint256 maxSlippageBps
) external view returns (bool verified)

However, this parameter is never used to validate recipients. The calldata contains two levels of recipient addresses:

  1. Top-level recipient in SlippageAndActions.recipient

  2. Action-level recipients in individual swap actions

Neither is validated against the owner parameter.

Code Evidence

Location 1: Top-Level Recipient Not Validated (Lines 127-131)

Location 2: Action Recipient Discarded (Lines 239-246)

Impact

The library's stated purpose is to validate untrusted calldata from the 0x API (as confirmed by team: "we do not trust this calldata blindly"). However, it fails to validate the most critical field - where the output tokens go.

The library accepts an owner parameter, suggesting it will validate ownership/recipients, but this parameter is never used for recipient validation.

Recommendation

Add Recipient Validation

Validate Top-Level Recipient

Proof of Concept

Proof of Concept

Add this to /test

Running the PoC

PoC Output

Was this helpful?