Listen to this Post
The vulnerability arises from Mezo’s EVM dual-context state architecture for precompile calls. When `bridgeOut` precompile invokes `burnERC20` for ERC-20 tokens, it calls `ExecuteContractCall` which creates a fresh inner `StateDB` operating on a `cachedCtx` branched from the base context. This inner burn reduces balance, allowance, and supply, then commits to `cachedCtx` and discards the inner DB – without creating any journal entry. Meanwhile, the outer `StateDB` retains stale pre-burn values in its `dirtyStorage` (from an earlier `approve` call) and never loads the updated balance slots. After `bridgeOut` returns, the attacker triggers a `transfer(recipient, 1)` which forces the outer `StateDB` to call `GetCommittedState` on the balance slot, reading the stale pre-burn value from `baseCtx` (since `cachedCtx` changes not yet flushed). It writes `staleBalance – 1` into dirtyStorage. At transaction commit, `StateDB.Commit()` first flushes `cachedCtx` → `baseCtx` (inner burn lands), then iterates every `dirtyStorage` entry and unconditionally writes to baseCtx, overwriting the burned balance and allowance with stale values. However, `SaveAssetsUnlocked` already persisted the unlock event to a different KV store prefix on cachedCtx, which survives the flush and triggers the L1 sidecar to release real tokens. The attacker’s Mezo balance remains unchanged, and the drain can be repeated each block.
DailyCVE form:
Platform: Mezo bridge
Version: v7.0.0 (prior)
Vulnerability : StateDB stale overwrite
Severity: Critical
date: 2026-05-06
Prediction: Already patched (2025-01-15)
Analytics under What Undercode Say:
Clone vulnerable version git clone https://github.com/mezo-org/mezod.git cd mezod && git checkout v7.0.0 Build and init localnet make localnet-bin-clean make localnet-bin-init Start nodes (4 terminals) make localnet-bin-start node0,1,2,3 Deploy exploit (solidity) cd solidity && npm install npx hardhat run scripts/poc_exploit.ts --network localnet
Exploit:
Crafted contract calls `approve(bridge, amount)` → `bridgeOut(token, amount, …)` → `transfer(attacker, 1)` in one transaction. Outer `dirtyStorage` holds stale allowance; inner burn zeroes balance/allowance on cachedCtx; `transfer` forces stale SLOAD; commit order flushes inner then overwrites with stale values. Event `AssetsUnlocked` persists, sidecar releases L1 tokens. Attacker repeats per block with zero net cost.
Protection from this CVE:
- After `flushCache()` in
Commit(), clear anydirtyStorage/originStorageslots that overlap with those modified by inner context. - Make `burnERC20` create journal entries (like
burnBitcoin) so `syncJournalEntries()` propagates changes to outerStateDB, removing BTC/ERC-20 asymmetry.
Impact:
Full drain of ERC-20 tokens locked in L1 bridge (contract 0xF6680EA3b480cA2b72D96ea13cCAF2cFd8e6908c). At risk: ~1,753,958.4 USD across cbBTC, T, USDC, USDT, xSolvBTC, SolvBTC, FBTC, USDe, swBTC, DAI. Each exploit costs 1 wei, repeated per block.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

