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 V3
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_ERRORINSUFFICIENT_LIQUIDITYINSUFFICIENT_SHORTFALLPRICE_ERRORREJECTION
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?