58403 sc medium missing checks for transaction return values in moonwell strategies

Submitted on Nov 2nd 2025 at 00:29:18 UTC by @Another for Audit Comp | Alchemix V3arrow-up-right

  • Report ID: #58403

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

    • Smart contract unable to operate due to lack of token funds

    • Permanent freezing of funds

Description

Brief/Intro

MoonwellUSDCStrategy and MoonwellWETHStrategy contracts interact with Moonwell mToken contracts (mint and redeemUnderlying) during allocation and deallocation but do not check the return values from these calls. Moonwell's mToken operations return error codes rather than reverting on failure, which means these strategy contracts proceedz as if operations succeeded when they actually failed, potentially leaving funds stuck or the protocol in an inconsistent state.

Vulnerability Details

According to Moonwell's documentation and contract code , , mToken operations follow a specific pattern:

// From Moonwell MErc20.sol
function mint(uint mintAmount) external override returns (uint) {
    (uint err, ) = mintInternal(mintAmount);
    return err; // Returns error code, doesn't revert
}

function redeemUnderlying(uint redeemAmount) external override returns (uint) {
    return redeemUnderlyingInternal(redeemAmount); // Returns error code
}

The operations return uint error codes from the TokenErrorReporter enum , which includes various failure scenarios such as:

  • MATH_ERROR

  • INSUFFICIENT_LIQUIDITY

  • INSUFFICIENT_SHORTFALL

  • PRICE_ERROR

  • REJECTION

MoonwellUSDCStrategy and MoonwellWETHStrategy however do not check for this return value and proceed as if the operation succeeded, which can lead to silent failures. This means, upon allocation or deallocation, mint or redeemUnderlying may fail, return an error code, which the strategies do not check for.

Impact Details

Because the error code is not checked, allocations, deallocations will silently fail, and internal accounting may diverge from its actual holdings in Moonwell, potentially making the protocol unable to fulfill withdrawal requests. In worst-case scenarios, user funds could become permanently stuck in the strategy without a clear way to recover them.

References

https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/strategies/optimism/MoonwellUSDCStrategy.sol#L52

https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/strategies/optimism/MoonwellUSDCStrategy.sol#L59

https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/strategies/optimism/MoonwellWETHStrategy.sol#L50

https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/strategies/optimism/MoonwellWETHStrategy.sol#L57

https://github.com/moonwell-fi/moonwell-contracts-v2/blob/347c6ceb1fb2215615c349d76a0bba21722f8677/src/MErc20.sol#L55

https://github.com/moonwell-fi/moonwell-contracts-v2/blob/1f09a0a01c0f98ce33f3c75f84e557466adb4280/src/MErc20.sol#L115

Proof of Concept

Proof of Concept

We create and run the following test file.

Was this helpful?