For the complete documentation index, see llms.txt. This page is also available as Markdown.

57516 sc low arbitrary external call in zeroxswapverifier leads to theft of unclaimed yield

Submitted on Oct 26th 2025 at 21:33:36 UTC by @dray for Audit Comp | Alchemix V3

  • Report ID: #57516

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Theft of unclaimed yield

Description

Brief/Intro

The ZeroXSwapVerifier.verifySwapCalldata() function fails to validate the from address in TRANSFER_FROM actions within 0x protocol swaps. An attacker can exploit this by crafting a malicious 0x swap payload that includes a transferFrom(strategy, attacker, amount) action, draining all yield tokens approved to the 0x Settler. Since strategies (like the Transmuter) pre-approve the 0x Settler with unlimited allowance, the attacker can steal all tokens held by the strategy contract through a legitimate-looking swap operation.

Vulnerability Details

Root Cause The ZeroXSwapVerifier.sol validates individual actions within 0x protocol swaps, but the _verifyTransferFrom() function fails to check that tokens are being transferred from the user, not from the contract itself:

function _verifyTransferFrom(bytes memory action, address owner, address targetToken, uint256 targetAmount) internal view {
    (address token, , , uint256 amount) = abi.decode(
        _sliceSkipSelector(action),
        (address, address, address, uint256)
    );
    
    require(token == targetToken, "Token mismatch");
    
    // ❌ MISSING: Validation that 'from' address is 'owner', not the contract!
    // The decoded parameters are: (token, from, to, amount)
    // But we never check that 'from == owner'
}

The full signature of the TRANSFER_FROM action (selector 0x8d68a156) is:

The verifier decodes all four parameters but only validates the token parameter. It never checks that from == owner, allowing an attacker to set from to the strategy contract address.

The verifier has several checks, but none prevent this exploit:

Settler validation: Only checks that the target is the legitimate 0x Settler contract Action type validation: TRANSFER_FROM (0x8d68a156) is a valid 0x action type Token validation: The verifier checks token == targetToken, which passes Amount validation: Not enforced for TRANSFER_FROM actions From address validation: COMPLETELY MISSING

Impact Details

Direct Financial Loss Total funds at risk: All tokens approved to the 0x Settler by any strategy contract.

Affected scenarios: Transmuter: All MYT (yield tokens) held in the Transmuter when used with ZeroXSwapVerifier Any strategy: Any ERC20 tokens that strategies approve to the 0x Settler for swap operations Multi-token exposure: If strategies approve multiple tokens, all are at risk

References

Vulnerable contract: ZeroXSwapVerifier.sol (lines 238-249, _verifyTransferFrom function)

Proof of Concept

Proof of Concept

Was this helpful?