57983 sc low direct asset drain via zeroxswapverifier bypass and mytstrategy unlimited permit2 approvals

Submitted on Oct 29th 2025 at 19:28:39 UTC by @rshackin for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57983

  • 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

    • Protocol insolvency

Description

Summary:

The ZeroXSwapVerifier library fails to enforce critical calldata fields (recipient, buyToken, minAmountOut, from, to) when validating 0x Settler EXECUTE payloads, allowing malicious routes that redirect funds to arbitrary recipients to pass verification. Combined with MYTStrategy's unlimited, owner-configurable Permit2 approvals on the receipt token, this enables direct theft of strategy custodied assets via crafted calldata that "verifies" but transfers tokens from the strategy to an attacker under the standing allowance.

When combined with MYTStrategy's unlimited, owner-configurable Permit2 approvals on custody tokens, this enables direct theft of all strategy-held MYT collateral and causes protocol-wide insolvency by creating unfulfillable transmuter redemption obligations.

Vulnerability Details

  1. Root Cause 1: ZeroXSwapVerifier Does Not Bind Recipients or Amounts. Functions: verifySwapCalldata, _verifyExecuteCalldata, _verifyTransferFrom.

  • Issue 1.1: The _verifyExecuteCalldata function decodes the SlippageAndActions struct containing recipient, buyToken, and minAmountOut, but never validates these fields:

  • Issue 1.2: The _verifyTransferFrom branch decodes (address token, address from, address to, uint256 amount) but only requires token == targetToken, completely ignoring from and to:

  • Issue 1.3: The owner parameter is passed through the call chain but never enforced in any action validation path, so unauthorized spenders and recipients are not detected.

Consequence: An attacker can craft EXECUTE calldata with TRANSFER_FROM(receiptToken, strategy, attacker, drainAmount) that passes verification despite explicitly draining the strategy to an external address.

  1. Root Cause 2: MYTStrategy Unlimited Permit2 Approvals. Functions: constructor, setPermit2Address. Issue: Both the constructor and admin setter grant unlimited approval on the receipt token to a configurable Permit2 address:

Consequence: Once Permit2 (or any configured address standing in for it) is set, the standing allowance enables anyone holding "verified" calldata to trigger transferFrom(strategy, attacker, amount) under that approval, with no per-transaction authorization required from the strategy.

Combined Attack Path:

Prerequisites:

  • MYTStrategy has been deployed with a Permit2 address (normal operation).

  • Strategy holds receipt tokens in custody (vault shares or similar in-scope assets). Attack Steps:

  1. Attacker crafts 0x Settler EXECUTE payload:

  1. Verification passes:

  1. Settlement executes drain:

  1. Result: Receipt tokens move from strategy custody to attacker, with no enforcement of recipient/owner at any boundary in these contracts.

  • Attacker repeats Steps 1-3 for every deployed MYTStrategy.

Impact :

  1. Direct theft of user funds: All MYT tokens held in strategy custody. (Assets at Risk):

  • Primary: All MYT (receipt tokens) held in MYTStrategy custody

  • Scale: 100% of strategy balances across all deployed strategies.

  • Irreversibility: Tokens transferred to attacker's EOA; no built-in recovery mechanism.

  1. Protocol insolvency: Permanent deficit between liabilities (earmarked debt, pending redemptions) and available assets, rendering transmuter claims unfulfillable and locking user withdrawals indefinitely.

References:

(https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/utils/ZeroXSwapVerifier.sol#L99-L130)

  • Enforce SlippageAndActions Fields in Verifier:

  • Bind from/to in TRANSFER_FROM:

  • Scope Permit2 Approvals in Strategy:

Proof of Concept

Proof of Concept:

Results:

Was this helpful?