57227 sc medium unchecked return codes in moonwellusdcstrategy leading to stuck funds

Submitted on Oct 24th 2025 at 14:49:36 UTC by @Pig46940 for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #57227

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

    • Permanent freezing of funds

Description

Brief/Intro

The MoonwellUSDCStrategy contains a vulnerability due to unchecked return values from external protocol calls. Specifically, the strategy calls mint() on the underlying mToken contract without verifying success, assuming these operations always succeed. However, the Moonwell contract’s mint() function return an error code instead of reverting when they fail. This can cause funds to become locked in the MoonwellUSDCStrategy contract.

Vulnerability Details

The Moonwell contracts explicitly describe the return values of mint() when an operation fails:

  • MErc20.sol: @return uint 0 = success, otherwise a failure (see ErrorReporter.sol for details)

/**
 * @notice Sender supplies assets into the market and receives mTokens in exchange
 * @dev Accrues interest whether or not the operation succeeds, unless reverted
 * @param mintAmount The amount of the underlying asset to supply
 * @return uint 0 = success, otherwise a failure (see ErrorReporter.sol for details)
 */
function mint(uint mintAmount) external returns (uint) {
    (uint err,) = mintInternal(mintAmount);
    return err;
}

The MoonwellUSDCStrategy fails to check the return values from the underlying mToken contract, which can lead to funds being locked. The mint() returns an error code instead of reverting, but the strategy assumes that the operations always succeed, as shown below:

  • MoonwellUSDCStrategy.sol

  • Fix suggestion:

Impact Details

The strategy assumes that all mToken operations always succeed. However, Moonwell mTokens return error codes instead of reverting, and because these return values are not checked, failures can pass silently. It will cause following impacts.

  • If mint() fails, the USDC remains in the strategy contract instead of being deposited, resulting in stuck user's funds.

References

  • https://github.com/moonwell-fi/contracts-open-source/blob/e23657c5fbeb12c7393fa49da6f350dc0bd5114e/contracts/core/MErc20.sol#L39

  • https://github.com/moonwell-fi/contracts-open-source/blob/c7da88a3fe3f0062d8a83ba808b648f1da369fec/contracts/core/ErrorReporter.sol#L4

  • https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/strategies/optimism/MoonwellUSDCStrategy.sol

Proof of Concept

Proof of Concept

The PoC shows that the strategy ignores Moonwell’s error-code return pattern, treating failed mint() calls as successes. This causes deposits to silently fail, leaving USDC stuck. As a result, normal users can face stuck funds.

  • Create to ./src/test/strategies/MoonwellUSDCStrategyVol.t.sol

  • Run the test code

Was this helpful?