This is a lower bound: only assets with reliable historical USD prices are counted, so the actual loss may be higher.
0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd0x5aa322875a7c089c1db8ae67b6fc5abd11cf653dMantle0xfa1444ac7917d6b96cac8307e97ed9c862e387beMantle0x5edbd8808f48ffc9e6d4c0d6845e0a0b4711fd5cMantleOn Mantle (chainid 5000), EOA 0x618f768af6291705eb13e0b2e96600b3851911d1 sends contract-creation transaction 0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd in block 66416577. The transaction deploys an orchestrator contract 0x5fdac50aa48e3e86299a04ad18a68750b2074d2d which, inside its constructor, executes a series of lending and liquidation calls against the Minterest Mantle deployment: the MUSDYToken_Mantle market 0x5edbd8808f48ffc9e6d4c0d6845e0a0b4711fd5c, the METHL2 market proxy 0x5aa322875a7c089c1db8ae67b6fc5abd11cf653d, and the BVM_ETH reserve proxy 0xfa1444ac7917d6b96cac8307e97ed9c862e387be.
Using only public entrypoints and prevailing oracle prices from the AggregatedPriceOracle controller 0x067820894867c71672387282533d3d3abad44095, the orchestrator repays undercollateralized debt and seizes collateral in METHL2 and BVM_ETH, routing the underlying assets through a helper contract 0x9b506584a0f2176494d5f9c858437b54df97bc06 and ultimately to the EOA. No lending or reserve invariants are broken and no unauthorized mint occurs; the incident is a permissionless liquidation MEV opportunity where a competitive liquidator extracts value from undercollateralized borrowers.
Minterest’s Mantle deployment uses a standard Compound-style money-market architecture, implemented via MToken_Mantle contracts behind proxy addresses. For this incident, the key markets are:
0x5aa322875a7c089c1db8ae67b6fc5abd11cf653d (implementation ).0xf8e2459f6961aba36c218ad35dc7077053ccb9580xfa1444ac7917d6b96cac8307e97ed9c862e387be (implementation 0xeb70eb1a325b03796ae8280bdba38ee4885d3853).0x5edbd8808f48ffc9e6d4c0d6845e0a0b4711fd5c.Each MToken market tracks:
totalTokenSupply, totalBorrows, totalProtocolInterest, borrowIndex, and per-account BorrowSnapshot and accountTokens.// From MToken.sol (MToken_Mantle implementation)
function exchangeRateStoredInternal() internal view returns (uint256) {
if (totalTokenSupply == 0) {
return initialExchangeRateMantissa;
} else {
return ((getCashPrior() + totalBorrows - totalProtocolInterest) * EXP_SCALE) / totalTokenSupply;
}
}
Borrow balances are tied to borrowIndex via borrowBalanceStoredInternal, and updates to totalBorrows and totalProtocolInterest occur only through interest accrual (accrueInterest) and explicit borrow/repay/liquidation paths. A Supervisor contract enforces risk checks via hooks such as beforeBorrow, beforeRedeem, beforeAutoLiquidationRepay, and beforeAutoLiquidationSeize.
Price data comes from AggregatedPriceOracle at 0x067820894867c71672387282533d3d3abad44095, which reads Api3 Dapi feeds to provide:
getUnderlyingPrice(METHL2 mToken) for the METHL2 market.getAssetPrice(BVM_ETH) for BVM_ETH.The markets are intentionally permissionless: when a borrower’s health factor (computed from Supervisor configuration and oracle prices) falls below the liquidation threshold, any actor can call autoLiquidationRepayBorrow and autoLiquidationSeize to repay debt and seize collateral at a discount. This design creates the possibility of liquidation MEV whenever undercollateralized positions exist.
The incident is not a protocol bug but a design-consistent MEV opportunity. At pre-state σ_B (Mantle block 66416577), at least one borrower in the MUSDYToken_Mantle and/or METHL2 markets is undercollateralized according to Supervisor checks using AggregatedPriceOracle prices. The MToken markets expose public, permissionless auto-liquidation entrypoints that allow any account to repay this debt and seize more collateral value (in METHL2 and BVM_ETH) than the cost of repayments and gas.
The core lending invariants remain intact:
exchangeRateStoredInternal formula above.borrowIndex.totalBorrows and totalProtocolInterest change only via accrueInterest and borrow/repay/liquidation functions.PrestateTracer storage diffs for 0x5aa3...653d, 0x5edb...1fd5c, and 0xfa14...87be show incremental changes in low-index slots (matching these global variables) and hashed mapping slots (account positions), consistent with normal borrow, repay, and liquidation updates. No evidence appears of arbitrary state resets or unauthorized minting.
The root cause is therefore economic: a permissionless liquidation mechanism, parameterized by oracle prices and risk settings, exposes undercollateralized positions to anyone who can perform the liquidation, allowing third parties to extract liquidation MEV at borrowers’ expense.
The relevant MToken functions are implemented in MToken.sol (verified via:
artifacts/root_cause/data_collector/iter_3/contract/5000/0xf8e2459f6961aba36c218ad35dc7077053ccb958/source/src/MToken.sol and the analogous file for 0xeb70...3853).
Key operations:
accrueInterest() updates totalBorrows, totalProtocolInterest, and borrowIndex according to an interest rate model and protocolInterestFactorMantissa.borrow / borrowFresh increase accountBorrows[borrower].principal and totalBorrows while transferring underlying out via doTransferOut:function borrowFresh(uint256 borrowAmount, bool isERC20based) internal nonReentrant {
address borrower = msg.sender;
supervisor.beforeBorrow(this, borrower, borrowAmount);
require(getCashPrior() >= borrowAmount, ErrorCodes.INSUFFICIENT_TOKEN_CASH);
uint256 accountBorrowsNew = borrowBalanceStoredInternal(borrower) + borrowAmount;
uint256 totalBorrowsNew = totalBorrows + borrowAmount;
accountBorrows[borrower].principal = accountBorrowsNew;
accountBorrows[borrower].interestIndex = borrowIndex;
totalBorrows = totalBorrowsNew;
if (isERC20based) doTransferOut(borrower, borrowAmount);
}
autoLiquidationRepayBorrow and autoLiquidationSeize implement liquidations for undercollateralized borrowers, gated solely by Supervisor hooks:function autoLiquidationRepayBorrow(address borrower_, uint256 repayAmount_) external nonReentrant {
supervisor.beforeAutoLiquidationRepay(msg.sender, borrower_, this);
require(accrualBlockNumber == getBlockNumber(), ErrorCodes.MARKET_NOT_FRESH);
require(totalProtocolInterest >= repayAmount_, ErrorCodes.INSUFFICIENT_TOTAL_PROTOCOL_INTEREST);
uint256 borrowBalance = borrowBalanceStoredInternal(borrower_);
accountBorrows[borrower_].principal = borrowBalance - repayAmount_;
accountBorrows[borrower_].interestIndex = borrowIndex;
totalBorrows -= repayAmount_;
totalProtocolInterest -= repayAmount_;
}
function autoLiquidationSeize(
address borrower_,
uint256 seizeUnderlyingAmount_,
bool isLoanInsignificant_,
address receiver_
) external nonReentrant {
supervisor.beforeAutoLiquidationSeize(this, msg.sender, borrower_);
uint256 exchangeRateMantissa = exchangeRateStoredInternal();
uint256 borrowerSeizeTokens;
if (seizeUnderlyingAmount_ == type(uint256).max) {
borrowerSeizeTokens = accountTokens[borrower_];
seizeUnderlyingAmount_ = (borrowerSeizeTokens * exchangeRateMantissa) / EXP_SCALE;
} else {
borrowerSeizeTokens = (seizeUnderlyingAmount_ * EXP_SCALE) / exchangeRateMantissa;
}
uint256 borrowerTokensNew = accountTokens[borrower_] - borrowerSeizeTokens;
uint256 totalSupplyNew = totalTokenSupply - borrowerSeizeTokens;
accountTokens[borrower_] = borrowerTokensNew;
totalTokenSupply = totalSupplyNew;
if (isLoanInsignificant_) {
totalProtocolInterest = totalProtocolInterest + seizeUnderlyingAmount_;
} else {
doTransferOut(receiver_, seizeUnderlyingAmount_);
}
}
These functions:
accrualBlockNumber == getBlockNumber()).doTransferOut(receiver_, seizeUnderlyingAmount_) when Supervisor has authorized liquidation.Admin-only functions (e.g., sweepToken, setProtocolInterestFactor) cannot be called by the orchestrator/helper and do not explain the observed value transfer.
Pre-state σ_B is reconstructed for the seed tx using:
artifacts/root_cause/seed/5000/0xb3c4...5bd/metadata.jsonartifacts/root_cause/seed/5000/0xb3c4...5bd/balance_diff.json0x5aa3...653d:
artifacts/root_cause/data_collector/iter_2/tx/5000/0xb3c4...5bd/state_diff_0x5aa322875a7c089c1db8ae67b6fc5abd11cf653d.json0x5edb...1fd5c:
artifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4...5bd/state_diff_0x5edbd8808f48ffc9e6d4c0d6845e0a0b4711fd5c.json0xfa14...87be:
artifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4...5bd/state_diff_0xfa1444ac7917d6b96cac8307e97ed9c862e387be.jsonOracle simulations at the parent block are captured in:
METHL2 oracle:
AggregatedPriceOracle::getUnderlyingPrice(MintProxy: 0x5aa3...653d)
→ 3315169076041807225751 [~3.315e21]
BVM_ETH oracle:
AggregatedPriceOracle::getAssetPrice(0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111)
→ 3193431400000000000000 [~3.193e21]
(From oracle_getUnderlyingPrice_METHL2.raw and oracle_getAssetPrice_BVM_ETH.raw.)
These values confirm that both the METHL2 underlying and BVM_ETH are high-value assets at σ_B, so any sizeable inflow of these tokens to the adversary represents economically meaningful profit.
The prestateTracer diffs for the core markets show:
0x5aa3...653d (METHL2 market), slots that match:
accrualBlockNumber, borrowIndex, totalBorrows, totalProtocolInterest, totalTokenSupply, and a small set of hashed mapping slots move from positive pre-state values to slightly larger post-state values.0x5edb...1fd5c (MUSDYToken_Mantle) and 0xfa14...87be (BVM_ETH reserve), the same pattern holds: low-index globals (interest/borrow/supply fields) and a handful of mapping slots change incrementally.This behavior is exactly what the MToken invariant requires when interest accrues, borrows are repaid, and collateral is seized. There is no evidence of:
The code-level invariant therefore holds across the incident.
The ERC20 and native balance diffs for the adversary EOA are:
{
"native_balance_deltas": [
{
"address": "0x618f768af6291705eb13e0b2e96600b3851911d1",
"before_wei": "223338207881203922053",
"after_wei": "222598952345423922053",
"delta_wei": "-739255535780000000"
}
],
"erc20_balance_deltas": [
{
"token": "0xdeaddeaddeaddeaddeaddeaddeaddeaddead1111",
"holder": "0x618f768af6291705eb13e0b2e96600b3851911d1",
"delta": "223640470785331714615",
"contract_name": "BVM_ETH"
},
{
"token": "0xcda86a272531e8640cd7f1a92c01839911b90bb0",
"holder": "0x618f768af6291705eb13e0b2e96600b3851911d1",
"delta": "204486893253187905361",
"contract_name": "METHL2"
}
]
}
(Summarized from balance_diff.json.)
The protocol/system holders lose the same amounts:
0xfa1444ac7917d6b96cac8307e97ed9c862e387be:
delta = -223640470785331714615 BVM_ETH.0x5aa322875a7c089c1db8ae67b6fc5abd11cf653d:
delta = -204486893253187905361 METHL2.Taking BVM_ETH as the reference asset and valuing METHL2 at zero for a conservative lower bound, the adversary’s portfolio change over sequence b (the single seed tx) is:
value_before_in_reference_asset = 0 BVM_ETH.value_after_in_reference_asset = 223.640470785331714615 BVM_ETH.fees_paid_in_reference_asset ≈ 0.73925553578 BVM_ETH-equivalent of gas/L1 fees.value_delta_in_reference_asset = 223.640470785331714615 - 0.73925553578 = 222.901215249551714615 BVM_ETH.This net gain is strictly positive and does not depend on any assumptions about the value of METHL2 or residual liabilities at helper contracts. The success predicate of the ACT opportunity is therefore:
222.90 BVM_ETH-equivalent after transaction fees.The adversary-related cluster accounts are:
0x618f768af6291705eb13e0b2e96600b3851911d1
0xb3c4...5bd.0x5fdac50aa48e3e86299a04ad18a68750b2074d2d
0xb3c4...5bd.0x9b506584a0f2176494d5f9c858437b54df97bc06
The seed transaction’s trace (trace.cast.log) shows heavy in-tx use of the helper and orchestrator, with calls into:
0x5aa3...653d and 0xfa14...87be.b: In-Block Liquidation and Profit RealizationThe ACT transaction sequence b consists of a single existentially-quantified adversary-crafted transaction:
5000).0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd (block 66416577).Within this tx:
The EOA deploys the orchestrator, which in its constructor:
0x067820894867c71672387282533d3d3abad44095.0x5aa3...653d.0xfa14...87be.0x5edb...1fd5c.0x5be26527e817998a7206475496fde1e68957c5a6.0xab575258d37eaa5c8956efabe71f4ee8f6397cf3.0x9b50...bc06 as the execution vehicle for liquidation.The helper adjusts an existing leveraged position in the MUSDYToken_Mantle market by:
The helper calls the METHL2 market and BVM_ETH reserve MToken implementations:
autoLiquidationRepayBorrow and autoLiquidationSeize for undercollateralized borrower accounts, as indicated by:
totalBorrows and totalProtocolInterest adjust in line with repayments.accountTokens and totalTokenSupply decrease for the liquidated borrowers.The EOA receives:
+223.640470785331714615 BVM_ETH from 0xfa14...87be.+204.486893253187905361 METHL2 from 0x5aa3...653d.0.73925553578 BVM_ETH-equivalent in gas/L1 fees.This entire sequence is realized in a single transaction whose constructor logic any unprivileged actor can deploy and execute, given the same pre-state σ_B.
After the seed tx, the EOA submits follow-up transactions:
0x2d5c8328dc8aacdbf4b4dc0367cbfda258197441cb3629f0bf4da0c573eb950e (block 66416654).0x5031e851a83e50725602110ba755f0e47cfb0790718125fe8fd29531ce1b1529 (block 66416670).0xe03b4147e8292a8cff85188726243847526d212c82390c52dffad23768d197af (block 66416687).0x53d694620fbe17cac1d06e5a89c1d12278d237692cc50aefc6c0479d8945a07f (block 66416701).The Etherscan-style txlist (artifacts/root_cause/data_collector/iter_1/address/5000/0x618f...11d1/txlist.json) shows that these are approvals and bridge/send operations through Mantle bridge/adapter contracts (e.g., 0x4c1d3f..., 0xf7628d...) to move a portion of the METHL2 and BVM_ETH off Mantle. These steps do not affect whether the ACT opportunity is profitable—the profit is already realized at the end of 0xb3c4...5bd—but they demonstrate how the adversary exports the MEV.
Under the defined ACT adversary model, any unprivileged actor could reproduce this strategy if the same type of undercollateralized positions exist:
autoLiquidationRepayBorrow and autoLiquidationSeize against undercollateralized borrowers.222.90 BVM_ETH-equivalent.This meets the definition of an ACT opportunity: the strategy uses only canonical on-chain data, public contract metadata/code, and standard, unprivileged transactions.
The immediate on-chain impact during tx 0xb3c4...5bd is:
0x5aa3...653d loses 204.486893253187905361 METHL2.0xfa1444ac7917d6b96cac8307e97ed9c862e387be loses 223.640470785331714615 BVM_ETH.0x618f...11d1 gains matching amounts of METHL2 and BVM_ETH.0.73925553578 BVM_ETH-equivalent in gas/L1 fees.Storage diffs for the affected markets show borrower debt and collateral balances decreasing in a way consistent with liquidation, not with arbitrary asset theft or invariant violation. The economic harm is borne by liquidated borrowers (and, where configured, protocol interest accounts), whose positions are forcibly closed and collateral is seized at a discount. The protocol itself remains solvent, and its accounting invariants hold.
From a protocol-design standpoint, this is an expected outcome of open, incentive-driven liquidations: the protocol intentionally allows third parties to capture liquidation spreads in exchange for maintaining system solvency.
0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd:
artifacts/root_cause/seed/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/metadata.jsonartifacts/root_cause/seed/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/balance_diff.jsonartifacts/root_cause/data_collector/iter_1/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/trace.cast.logartifacts/root_cause/data_collector/iter_1/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/receipt.jsonartifacts/root_cause/data_collector/iter_3/contract/5000/0xf8e2459f6961aba36c218ad35dc7077053ccb958/source/src/MToken.solartifacts/root_cause/data_collector/iter_3/contract/5000/0xeb70eb1a325b03796ae8280bdba38ee4885d3853/source/src/MToken.solartifacts/root_cause/data_collector/iter_2/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/state_diff_0x5aa322875a7c089c1db8ae67b6fc5abd11cf653d.jsonartifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/state_diff_0x5edbd8808f48ffc9e6d4c0d6845e0a0b4711fd5c.jsonartifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/state_diff_0xfa1444ac7917d6b96cac8307e97ed9c862e387be.jsonartifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/oracle_getUnderlyingPrice_METHL2.rawartifacts/root_cause/data_collector/iter_3/tx/5000/0xb3c4c313a8d3e2843c9e6e313b199d7339211cdc70c2eca9f4d88b1e155fd6bd/oracle_getAssetPrice_BVM_ETH.rawartifacts/root_cause/data_collector/iter_1/address/5000/0x618f768af6291705eb13e0b2e96600b3851911d1/txlist.json