MoonwellUSDCStrategy._allocate ignores Compound-style mint failures and corrupts vault accounting.
Bug Description
MoonwellUSDCStrategy._allocate(uint256 amount) approves USDC to the Moonwell market and calls mUSDC.mint(amount) without checking the return code. Compound-style markets (EIP-20) return 0 on success and a non-zero error on failure. Because _allocate blindly returns the requested amount, the vault records a successful deployment even when Moonwell rejected the mint, leaving the USDC stranded on the adapter and corrupting accounting.
Impact
False accounting: The vault believes capital was deployed while assets remain idle on the strategy. Subsequent deallocations assume inflated balances and can revert or underpay.
Operational freeze: If minting continues to fail, every allocation attempt silently reports success, leaving allocators unaware of the issue and preventing rebalancing.
The fork test logs show the vault recording the full 1,000 USDC allocation while realAssets() stays zero.
Risk Breakdown
Privileges required: Allocator/admin calling _allocate through the vault.
Likelihood: Medium – Moonwell markets can be paused during incidents (pause-guardian controls inherited from Compound via Comptroller) or return non-zero codes for transient errors.
Recommendation
Require the mint to succeed before reporting success:
Compound cToken specification confirming mint returns 0 on success and non-zero error codes otherwise (includes example assert(cToken.mint(100) == 0);): https://docs.compound.finance/v2/ctokens/#mint
ERC-20 specification warning: “Callers MUST handle false from returns (bool success). Callers MUST NOT assume that false is never returned!” — https://eips.ethereum.org/EIPS/eip-20#token
Proof of Concept
Proof of Concept
Allocation to the strategy with a mock mToken that returns error code 1 from mint. _allocate reports success even though no mTokens are minted.
Add the below code to the existing test suite src/test/strategies/MoonwellUSDCStrategy.t.sol
Run the following command in terminal forge t --mt test_mintFailureKeepsVaultAccountingInflated -vvv
uint256 result = mUSDC.mint(amount);
require(result == 0, "Moonwell mint failed");
import {IVaultV2} from "../../../lib/vault-v2/src/interfaces/IVaultV2.sol";
import {IERC20} from "../../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";