57989 sc low broken isvalidsignature leads to fund freezing

Submitted on Oct 29th 2025 at 20:26:42 UTC by @nem0thefinder for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57989

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Permanent freezing of funds

    • Wrong isValidSignature leads to permenant freeze of funds in strategies don't have direct withdraws or require swaps

Description

Summary

The isValidSignature() function in MYTStrategy attempts to delegate signature verification to Permit2 by calling IPermit2(permit2Address).isValidSignature(), which does not exist in the Permit2 contract. This causes all Permit2 operations where the strategy contract acts as the token owner to revert, resulting in a complete denial of service of any Permit2-based functionality

Description

The current implementation of isValidSignature() in MYTStrategy.sol:

function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) {
    return IPermit2(permit2Address).isValidSignature(_hash, _signature);
}

This implementation is fundamentally broken because:

  1. Permit2 does not have an isValidSignature function - The Permit2 contract (SignatureTransfer and AllowanceTransfer) does not expose any isValidSignature function. The interface IPermit2 defined in the contract is incorrect.

SignatureTransfer.sol: https://github.com/Uniswap/permit2/blob/main/src/SignatureTransfer.sol

AllowanceTransfer.sol: https://github.com/Uniswap/permit2/blob/main/src/AllowanceTransfer.sol

  1. Backwards delegation logic - When Permit2 calls permitTransferFrom() with a smart contract as the owner, it internally calls that contract's isValidSignature() for ERC-1271 validation. The strategy contract should validate signatures itself, not delegate back to Permit2.

  2. Incorrect understanding of ERC-1271 pattern - The ERC-1271 standard requires the implementing contract to verify signatures locally and return the magic value 0x1626ba7e if valid. The current implementation attempts to call an external contract instead.

How Permit2 Actually Works:

When ISignatureTransfer(permit2).permitTransferFrom(permit, details, owner, signature) is called it initiaite an intenral call to signatureVerify lib which validate the sig:

_permitTransfer: https://github.com/Uniswap/permit2/blob/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219/src/SignatureTransfer.sol#L65

Signature::verify: https://github.com/Uniswap/permit2/blob/cc56ad0f3439c502c246fc5cfcc3db92bb8b7219/src/libraries/SignatureVerification.sol#L42C8-L44C101

When the owner is the strategy contract, Permit2 calls the strategy's isValidSignature(), which then tries to call Permit2's non-existent isValidSignature(), causing the transaction to revert.

Impact

  1. PermenantFreezeOfFunds- Based on protocol team intentions permit2 gonna used with 0x in strategies that don't have the ability to instantly withdraw, or require swaps.leaving the funds allocated forever

  2. 100% failure rate - Any call to permitTransferFrom() where the strategy is the token owner will always revert

  3. No workaround available - MytStrategy is not upgradeable and The function will revert before any token transfer logic executes

  4. Affects all future Permit2 features - Any planned signature-based transfers, gasless transactions, or whitelisted allocator operations using Permit2 will be permanently broken

  5. Blocks ZeroX integration -Third-party protocols attempting to integrate with the strategy via Permit2 will fail

Mitigation

  • Replace the current implementation with proper ERC-1271 signature verification

Proof of Concept

Proof of Concept

Note Permit2AddressMainnet= 0x000000000022d473030f116ddee9f6b43ac78ba3

1. Import the following test in MYTStrategy.t.sol

2.Run it via forge test --mc MYTStrategyTest --mt test_isValidSignature_always_revert -vvv

Logs

Was this helpful?