MineSTM / STMERC20 Inner Pair MEV Drain
Exploit Transactions
0x40f3bdd0a3a8d0476ae6aa2875dc2ec60b80812e2a394b67a88260df57c65522Victim Addresses
0xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6BSC0x2e45aef311706e12d48552d0daa8d9b8fb764b1cBSCLoss Breakdown
Similar Incidents
MineSTM LP-burn MEV drains USDT from STM liquidity
47%DysonVault / Thena Overnight LP Unwind MEV
32%AIZPT314 bonding-curve arbitrage drains BNB reserves via flash swap
28%CS Pair Balance Burn Drain
27%StarlinkCoin Pair Drain
25%SellToken Arbitrary-Pair LP Drain
23%Root Cause Analysis
MineSTM / STMERC20 Inner Pair MEV Drain
1. Incident Overview TL;DR
On BNB Chain (chainid 56), the MineSTM protocol configured a private STMERC20/USDT “inner” AMM pair and then used an owner-only function to push a very large amount of STMERC20 into that pair without adding USDT or synchronising reserves. This left the inner pair’s on-chain STMERC20 balance far above its stored reserves, so the pair quoted an artificially cheap STMERC20 price to external traders.
An unprivileged adversary deployed a simple router contract and, in a single transaction (0x40f3bdd0a3a8d0476ae6aa2875dc2ec60b80812e2a394b67a88260df57c65522 in block 39381374), executed a flash swap that routed 50 USDT through this mispriced inner STMERC20/USDT pair and the MineSTM contract. After repaying the flash loan, approximately 91.7k USDT of protocol-owned liquidity was transferred to adversary EOA 0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e.
The core root cause is a protocol-owned liquidity configuration error: MineSTM’s owner-only withOutToken function, combined with STMERC20’s inner-pair routing and the inner pair’s reserve update rules, allowed the owner to create a large, publicly exploitable price gap between the inner STMERC20/USDT pair and the external STMERC20/USDT market.
2. Key Background
MineSTM (0xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6) is an Ownable protocol contract that manages STMERC20- and USDT-denominated investment flows and liquidity on BNB Chain. It holds protocol-owned STMERC20 (EVE token) and USDT balances and interacts with an “inner” liquidity pair to manage pooled liquidity.
STMERC20 (0xbd0df7d2383b1ac64afeafdd298e640efd9864e0) is an Ownable ERC‑20 token with a custom transfer fee on the public STMERC20/USDT pair and a dedicated inner pair for protocol-owned liquidity. The token tracks a mapping of addresses that are allowed to send STMERC20 directly into the inner pair:
mapping (address => bool) private _isInnerRouterOwnerShips;
IPancakeRouter private constant innerRouter = IPancakeRouter(0x0ff0eBC65deEe10ba34fd81AfB6b95527be46702);
address public immutable innerPair;
function _transfer(address from, address to, uint256 amount) internal override {
if(to == innerPair) {
require(_isInnerRouterOwnerShips[from], "f");
}
...
}
This configuration allows selected contracts (such as MineSTM) to move STMERC20 into the inner pair without paying the 5% fee charged on transfers involving the public STMERC20/USDT pair, and ensures that only authorised contracts can push into the inner pair at all.
The inner STMERC20/USDT pair (0x2e45aef311706e12d48552d0daa8d9b8fb764b1c) is a Pancake-style constant-product AMM. Its decompiled code shows standard functions such as initialize, swap, mint, burn, and sync, with reserves tracked via an internal getReserves structure. As in Pancake/Uniswap V2, direct ERC‑20 transfers into the pair update the token balances but do not adjust the stored reserves until a subsequent swap, mint, burn, or sync is executed. This means a large direct transfer into the pair can temporarily create a “stale reserve” state where the actual balances and the reserves used for pricing diverge.
MineSTM hard-codes STMERC20 and the inner pair address and exposes an owner-only withOutToken function that allows the owner to move arbitrary ERC‑20 tokens from the MineSTM contract to any destination, including the inner pair:
// MineSTM.sol (verified source)
IERC20 private constant eve_token_erc20 = IERC20(0xBd0DF7D2383B1aC64afeAfdd298E640EfD9864e0);
IPancakePair private constant inner_pair = IPancakePair(0x2E45AEf311706e12D48552d0DaA8D9b8fb764B1C);
function withOutToken(address account,address account2,uint256 amount) public onlyOwner {
IERC20(account).transfer(account2, amount);
}
This design gives the MineSTM owner unilateral control over large protocol-owned STMERC20 transfers into the inner pair, without any built-in invariant checks or safety guards to prevent creating exploitable pricing conditions.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability is a protocol-owned liquidity misconfiguration that creates a stale-reserve mispricing in a private inner STMERC20/USDT pair. By depositing a very large amount of STMERC20 from MineSTM into the inner pair via a direct ERC‑20 transfer, the owner increased the pair’s STMERC20 balance without updating its stored reserves or adding USDT.
Because the pair only updates reserves on swap/mint/burn/sync, this direct deposit caused the inner pair to quote STMERC20 at an artificially cheap price relative to USDT when valued against the external STMERC20/USDT market. Any unprivileged adversary that could compose a flash swap and a trade against the inner pair could deterministically withdraw far more USDT than the fair market value of the STMERC20 given up, after fees.
The critical economic safety invariant is:
For protocol-owned STMERC20 liquidity held in the inner STMERC20/USDT pair 0x2e45aef311706e12d48552d0daa8d9b8fb764b1c, any publicly callable swap path starting and ending in the external market must not enable an external trader to withdraw more USDT from the inner pair than the fair market value of the STMERC20 it gives up, after accounting for all fees.
The first concrete breakpoint that violates this invariant is the owner-only call:
MineSTM.withOutToken(STMERC20, inner_pair, 1104052000000000000000000000)in tx 0x23f2f403af44707df6ed536ffd80bb7c7775d6be43b7e63669e9055aa3c53072 (block 39377892).
This call transfers 1.104052e24 STMERC20 from MineSTM into the inner STMERC20/USDT pair via a direct ERC‑20 transfer. Until a subsequent sync or swap updates reserves, the pair’s pricing function uses stale reserves that dramatically underprice STMERC20 relative to USDT. The adversary later exploits this mispricing in a single router transaction by routing a 50 USDT flash swap through the inner pair and MineSTM to drain ≈91.7k USDT of protocol-owned liquidity.
4. Detailed Root Cause Analysis
4.1 Victim-side configuration and invariants
From the verified STMERC20 source, the token defines an inner pair and a whitelist of senders allowed to transfer into that pair:
address public immutable innerPair;
mapping (address => bool) private _isInnerRouterOwnerShips;
function _transfer(address from, address to, uint256 amount) internal override {
if(to == innerPair) {
require(_isInnerRouterOwnerShips[from], "f");
}
...
}
The MineSTM contract is configured as an authorised sender via STMERC20’s owner-only innerRouterOwnerShips function, allowing MineSTM to push STMERC20 into the inner pair without fees and without restriction beyond owner control.
The decompiled inner pair contract shows a Pancake-style design with sync() updating reserves based on token balances, and typical swap/mint/burn logic that assumes balances only change via these functions. Direct transfers to the pair (such as from withOutToken) update the token balances but leave the internal reserves stale until one of these functions is called.
The intended invariant for protocol-owned liquidity is that, even when MineSTM moves STMERC20 into the inner pair, public traders should not be able to execute a single transaction that withdraws more USDT from the pair than the fair market value of STMERC20 they supply, after fees.
4.2 Owner-only priming transaction (breakpoint)
In block 39377892, the MineSTM owner EOA 0x50e48af70271ab36b5f48fd7162d5851eb692849 calls MineSTM.withOutToken:
- Tx: 0x23f2f403af44707df6ed536ffd80bb7c7775d6be43b7e63669e9055aa3c53072
- Call:
withOutToken(STMERC20, inner_pair, 1104052000000000000000000000)
The cast trace for this transaction shows MineSTM transferring STMERC20 from its own balance to the inner pair via a direct ERC‑20 transfer (no sync call is made in this tx). This operation:
- Increases the STMERC20 token balance held by the inner pair by 1.104052e24 tokens.
- Leaves the pair’s stored reserves unchanged until a later swap/mint/burn/sync.
- Does not add USDT to the pair.
As a result, the pair’s internal reserves drastically understate its STMERC20 holdings. The invariant is now violated: there exists a swap path in which an external trader can obtain more USDT value than the fair price of the STMERC20 given up, because the AMM pricing function will use stale reserves that underprice STMERC20.
4.3 Adversary contract deployment
Shortly before the exploit, adversary EOA 0xb2d546547168f61debf0a780210b5591e4dd39a8 deploys a small router contract (0xa4fd1beac3b5fb78a8ec074338152100b87437a9). The decompiled router shows a public function with selector 0x2ca3a7f9 that orchestrates calls to:
- A Pancake V3 pool for a USDT flash swap.
- The innerRouter and MineSTM contracts.
- The inner STMERC20/USDT pair.
The function is publicly callable: there is no owner or whitelist gating in the decompiled code. Any unprivileged EOA with sufficient gas can call this function using known, hard-coded addresses for USDT, STMERC20, the inner pair, innerRouter, MineSTM, and the profit EOA.
4.4 Exploit transaction and on-chain evidence
The exploit takes place in transaction:
- Chain: BNB Chain (56)
- Tx hash: 0x40f3bdd0a3a8d0476ae6aa2875dc2ec60b80812e2a394b67a88260df57c65522
- Block: 39381374
- Sender: EOA 0xb2d546547168f61debf0a780210b5591e4dd39a8
- Target: Router 0xa4fd1beac3b5fb78a8ec074338152100b87437a9
- Calldata selector: 0x2ca3a7f9
The balance_diff.json for this transaction shows the net ERC‑20 balance changes:
{
"token": "0x55d398326f99059ff775485246999027b3197955",
"holder": "0x2e45aef311706e12d48552d0daa8d9b8fb764b1c",
"before": "91756641426462709287653",
"after": "17815912326718118003",
"delta": "-91738825514135991169650"
},
{
"token": "0x55d398326f99059ff775485246999027b3197955",
"holder": "0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e",
"before": "0",
"after": "91688825514135991169650",
"delta": "91688825514135991169650"
}
For STMERC20:
{
"token": "0xbd0df7d2383b1ac64afeafdd298e640efd9864e0",
"holder": "0x2e45aef311706e12d48552d0daa8d9b8fb764b1c",
"before": "2740054541998103233948508",
"after": "12818489616984004992",
"delta": "-2740041723508486249943516"
},
{
"token": "0xbd0df7d2383b1ac64afeafdd298e640efd9864e0",
"holder": "0xa4fd1beac3b5fb78a8ec074338152100b87437a9",
"before": "0",
"after": "1888533492920270643450573",
"delta": "1888533492920270643450573"
},
{
"token": "0xbd0df7d2383b1ac64afeafdd298e640efd9864e0",
"holder": "0xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6",
"before": "6759945458001896766051492",
"after": "7611453688590112372544435",
"delta": "851508230588215606492943"
}
These diffs confirm:
- The inner pair loses 91,738.825514135991169650 USDT and 2,740,041,723,508,486,249,943,516 STMERC20.
- The router contract 0xa4fd1b... and MineSTM contract 0xb7d0a1... absorb large amounts of STMERC20.
- EOA 0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e receives 91,688.825514135991169650 USDT.
The native balance delta for the sender EOA is:
{
"address": "0xb2d546547168f61debf0a780210b5591e4dd39a8",
"before_wei": "40004058000000000",
"after_wei": "37066703000000000",
"delta_wei": "-2937355000000000"
}
This is a gas cost of 0.002937355 BNB.
4.5 Profit predicate and ACT opportunity
Using the USDT balances for the adversary-related accounts:
- Before the exploit, EOA 0xb5f1f0... holds 0 USDT.
- After the exploit, it holds 91,688.825514135984121822 USDT (from the delta).
- No other adversary-cluster address holds USDT before or after the transaction.
Even under an extreme bound of 1000 USDT per BNB, gas costs of 0.002937355 BNB are worth at most 2.9374 USDT. The adversary’s net USDT-denominated profit is therefore at least:
- 91,688.825514135984121822 − 2.9374 ≈ 91,685.8881 USDT.
This establishes a strictly positive profit predicate after fees.
The opportunity is an ACT (anyone-can-take) MEV opportunity:
- All required contracts (USDT, STMERC20, inner pair, innerRouter, MineSTM, router) are on-chain and publicly accessible.
- The router function with selector 0x2ca3a7f9 is publicly callable and uses only these known addresses.
- The pre-state mispricing is created by an owner-only MineSTM transaction but, once in place, any unprivileged EOA can deploy an equivalent router and execute the same strategy using canonical on-chain data and standard RPC calls.
5. Adversary Flow Analysis
5.1 Adversary-related cluster
The minimal adversary-related cluster is:
- EOA 0xb2d546547168f61debf0a780210b5591e4dd39a8: deployer of router 0xa4fd1b... and sender of the exploit tx 0x40f3bd....
- Router 0xa4fd1beac3b5fb78a8ec074338152100b87437a9: attacker-controlled contract with a public function (selector 0x2ca3a7f9) that orchestrates the exploit path.
- EOA 0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e: recipient of the entire USDT profit; no on-chain transfers in the analysed window send this USDT back to MineSTM or its owner.
5.2 End-to-end exploit sequence
Given the pre-state created by the owner’s withOutToken call, the adversary’s transaction 0x40f3bd... executes the following high-level steps within a single block:
-
Flash swap initiation
- The router calls a Pancake V3 pool (0x92b7807bf19b7dddf89b706143896d05228f3121) to borrow 50 USDT via a flash swap, with callback logic implemented in the router itself.
-
Routing USDT into the inner pair via innerRouter and MineSTM
- Using innerRouter 0x0ff0eBC65deEe10ba34fd81AfB6b95527be46702 and MineSTM, the router routes USDT into the MineSTM/inner pair path that will eventually trade against the mispriced inner STMERC20/USDT pool.
-
Swap against the mispriced inner pair
- The router invokes the inner pair to swap USDT for STMERC20. Because the pair’s reserves were not updated after the owner’s large STMERC20 deposit, the AMM still believes its STMERC20 reserve is much lower than the actual balance, so it offers STMERC20 at a price that is too cheap relative to USDT.
- As shown by the balance diffs, the inner pair loses approximately 2.740e24 STMERC20 and 9.174e22 USDT in this process.
-
Routing STMERC20 and repaying the flash swap
- The router uses MineSTM to move STMERC20 as needed and swaps or transfers STMERC20 to repay the 50 USDT plus fees back to the Pancake V3 pool.
-
Profit realisation
- After the flash swap is repaid, the router transfers the remaining USDT surplus (about 91.7k USDT) to EOA 0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e.
- The sender EOA pays only 0.002937355 BNB in gas, leaving a large net positive USDT-denominated profit.
5.3 Determinism and reproducibility
The strategy uses only:
- Public contract methods (
withOutTokenpre-state is already realised; exploit uses public swap and router functions). - Canonical on-chain data (reserves, balances, transaction traces).
- Standard flash-swap capabilities of Pancake V3.
Any other unprivileged EOA could reproduce the same effect by:
- Deploying a router that hard-codes the same contract addresses.
- Issuing a single transaction with function selector 0x2ca3a7f9 and matching parameters.
No private orderflow, special gas tricks, or privileged access are required.
6. Impact & Losses
From the balance_diff.json for tx 0x40f3bd...:
- The inner STMERC20/USDT pair 0x2e45ae...b1c loses:
- 91,738.825514135991169650 USDT.
- 2,740,041,723,508,486,249,943,516 STMERC20.
- MineSTM 0xb7d0a1... and the router 0xa4fd1b... end up holding large STMERC20 balances.
- EOA 0xb5f1f0... receives 91,688.825514135984121822 USDT.
The protocol’s realised USDT-denominated loss is 91,688.825514135984121822 USDT (ignoring any subsequent disposition of STMERC20). This depletes protocol-owned USDT liquidity in the inner pair, distorts STMERC20 pricing, and exposes MineSTM users to impaired liquidity and potential further arbitrage until the system is rebalanced or shut down.
7. References
-
Exploit transaction (seed tx):
- BNB Chain, tx 0x40f3bdd0a3a8d0476ae6aa2875dc2ec60b80812e2a394b67a88260df57c65522 (block 39381374).
- Evidence:
trace.cast.log,balance_diff.json, andmetadata.jsonunderartifacts/root_cause/seed/56/0x40f3bd....
-
Priming (breakpoint) transaction:
- BNB Chain, tx 0x23f2f403af44707df6ed536ffd80bb7c7775d6be43b7e63669e9055aa3c53072 (block 39377892), MineSTM owner calling
withOutToken(STMERC20, inner_pair, 1104052000000000000000000000). - Evidence:
trace.cast.logandmetadata.cast.jsonunderartifacts/root_cause/data_collector/iter_1/tx/56/0x23f2f4....
- BNB Chain, tx 0x23f2f403af44707df6ed536ffd80bb7c7775d6be43b7e63669e9055aa3c53072 (block 39377892), MineSTM owner calling
-
Victim contracts:
- MineSTM: 0xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6 (verified source in
artifacts/root_cause/data_collector/iter_1/contract/56/0xb7d0a1.../source/src/MineSTM.sol). - STMERC20: 0xbd0df7d2383b1ac64afeafdd298e640efd9864e0 (verified source in
artifacts/root_cause/seed/56/0xbd0df7.../src/STMERC20.sol). - Inner STMERC20/USDT pair: 0x2e45aef311706e12d48552d0daa8d9b8fb764b1c (decompiled source in
artifacts/root_cause/data_collector/iter_2/contract/56/0x2e45ae.../decompile/...-decompiled.sol).
- MineSTM: 0xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6 (verified source in
-
Adversary contracts and accounts:
- Router: 0xa4fd1beac3b5fb78a8ec074338152100b87437a9 (decompiled source in
artifacts/root_cause/data_collector/iter_1/contract/56/0xa4fd1b.../decompile/...-decompiled.sol). - Sender EOA: 0xb2d546547168f61debf0a780210b5591e4dd39a8.
- Profit EOA: 0xb5f1f0f3e9e72f94db32e8fcddde972ebfdc748e.
- Router: 0xa4fd1beac3b5fb78a8ec074338152100b87437a9 (decompiled source in
-
Analysis artifacts:
- Root cause analysis JSON: `<REDACTED_LOCAL_PATH>
- Analyzer iteration 4 result:
artifacts/root_cause/root_cause_analyzer/iter_4/current_analysis_result.json.