Calculated from recorded token losses using historical USD prices at the incident time.
0x40f3bdd0a3a8d0476ae6aa2875dc2ec60b80812e2a394b67a88260df57c655220xb7d0a1adafa3e9e8d8e244c20b6277bee17a09b6BSC0x2e45aef311706e12d48552d0daa8d9b8fb764b1cBSCOn 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.
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.
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.
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.
In block 39377892, the MineSTM owner EOA 0x50e48af70271ab36b5f48fd7162d5851eb692849 calls MineSTM.withOutToken:
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:
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.
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:
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.
The exploit takes place in transaction:
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 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.
Using the USDT balances for the adversary-related accounts:
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:
This establishes a strictly positive profit predicate after fees.
The opportunity is an ACT (anyone-can-take) MEV opportunity:
The minimal adversary-related cluster is:
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
Routing USDT into the inner pair via innerRouter and MineSTM
Swap against the mispriced inner pair
Routing STMERC20 and repaying the flash swap
Profit realisation
The strategy uses only:
withOutToken pre-state is already realised; exploit uses public swap and router functions).Any other unprivileged EOA could reproduce the same effect by:
No private orderflow, special gas tricks, or privileged access are required.
From the balance_diff.json for tx 0x40f3bd...:
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.
Exploit transaction (seed tx):
trace.cast.log, balance_diff.json, and metadata.json under artifacts/root_cause/seed/56/0x40f3bd....Priming (breakpoint) transaction:
withOutToken(STMERC20, inner_pair, 1104052000000000000000000000).trace.cast.log and metadata.cast.json under artifacts/root_cause/data_collector/iter_1/tx/56/0x23f2f4....Victim contracts:
artifacts/root_cause/data_collector/iter_1/contract/56/0xb7d0a1.../source/src/MineSTM.sol).artifacts/root_cause/seed/56/0xbd0df7.../src/STMERC20.sol).artifacts/root_cause/data_collector/iter_2/contract/56/0x2e45ae.../decompile/...-decompiled.sol).Adversary contracts and accounts:
artifacts/root_cause/data_collector/iter_1/contract/56/0xa4fd1b.../decompile/...-decompiled.sol).Analysis artifacts:
artifacts/root_cause/root_cause_analyzer/iter_4/current_analysis_result.json.