Calculated from recorded token losses using historical USD prices at the incident time.
0x8b528372b743b4b8c4eb0904c96529482653187c19e13afaa22f3ba4e08fbfbb0xe1747a23c44f445062078e3c528c9f4c28c50a51BSC0x3407c5398256cc242a7a22c373d9f252bab37458BSCOn BSC block 33503912, transaction 0x8b528372b743b4b8c4eb0904c96529482653187c19e13afaa22f3ba4e08fbfbb exploited Eterna's EHX token by forcing its contract to spend treasury BNB on a fixed-size buyback that any non-AMM sender could trigger. The attacker used a public DODO flash loan of 5.589328092301986679 WBNB, bought EHX, then repeatedly sent dust EHX amounts to the EHX/WBNB Pancake pair and immediately called the pair's public skim(address) function to recover most of the transferred tokens.
Each loop spent 0.001 BNB from the EHX contract treasury, burned the bought-back EHX to the dead address, and ratcheted the pair price upward. After 300 dust loops and one final sell-triggered buyback, the attacker sold the inflated EHX position back into WBNB, repaid the flash loan, and kept 0.131914943781835584 BNB net profit after gas. The root cause is a deterministic public spend primitive in Token._transfer(): arbitrary users can trigger a fixed treasury buyback that is unrelated to transfer size, and the Pancake pair's permissionless skim() makes the trigger loop economically cheap.
EHX is a fee-on-transfer token whose verified source sets totalFees = 250 and a fixed buyBackAmount = 10**15, which is 0.001 BNB. When a transfer comes from a non-AMM address and the token contract holds more than buyBackAmount * 10 native BNB, the token unconditionally spends treasury BNB on a buyback before finishing the user's transfer.
The bought-back EHX is not returned to users or retained in treasury. swapETHForTokens() routes the purchased EHX directly to the dead address, so every forced buyback removes EHX from circulation while injecting more WBNB into the pair's reserves. That pushes the EHX price upward if repeated often enough.
The other critical ingredient is the Pancake pair's public skim(address) behavior. When a fee-on-transfer token is sent to the pair, the pair can temporarily hold a balance surplus above its stored reserves. Anyone can call skim() to pull that surplus out. In this incident, that let the attacker recycle most of the dust EHX used to re-trigger the next fixed-size buyback.
The relevant EHX source behavior is visible in the verified token contract:
if (canBuyBack && address(this).balance > buyBackAmount * 10 && !automatedMarketMakerPairs[from] && !swapping) {
buyBackTokens(buyBackAmount);
}
function buyBackTokens(uint256 amount) private lockTheSwap {
if (amount > 0) {
swapETHForTokens(amount);
}
}
function swapETHForTokens(uint256 amount) private {
address[] memory path = new address[](2);
path[0] = uniswapV2Router.WETH();
path[1] = address(this);
uniswapV2Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amount}(
0,
path,
deadAddress,
block.timestamp
);
}
This incident is an ATTACK, not a benign MEV unwind. The vulnerable design is that EHX couples every qualifying non-AMM transfer to a fixed treasury spend of 0.001 BNB, regardless of the transfer's economic size. That means a user sending a dust-sized EHX transfer can force the same treasury outflow as a large real trade. Because the token spends before completing the transfer and because the attacker can repeatedly recover most of the dust via Pancake skim(), the treasury spend becomes a public loopable primitive. The violated invariant is straightforward: an unprivileged user must not be able to deterministically force disproportionate treasury spending through dust-sized public actions. The code-level breakpoint is the unconditional buyback branch in Token._transfer(). Once that branch is reachable, the only remaining requirement is access to public liquidity and the ability to cycle dust transfers through the pair.
The ACT pre-state immediately before the exploit was fully public and reconstructible. The EHX contract already held enough native BNB to satisfy the buyback arm condition, the EHX/WBNB pair had live liquidity, and the DODO pool at 0xfeafe253802b77456b4627f8c2306a9cebb5d681 could fund the flash loan. No privileged keys, private order flow, or privileged contract roles were needed.
The attacker path began with a public flash loan and an initial buy of EHX. The exploit helper contract borrowed 5.589328092301986679 WBNB, swapped into EHX, and then started the dust loop. The loop mechanics are visible directly in the seed trace:
Token::transferFrom(0x9D0d28f7b9a9e6D55abb9e41a87df133F316C68C,
PancakePair: [0x3407c5398256cc242a7a22c373D9F252BaB37458],
4349498877701)
PancakeRouter::swapExactETHForTokensSupportingFeeOnTransferTokens{value: 1000000000000000}(
0,
[WBNB, EHX],
0x000000000000000000000000000000000000dEaD,
...
)
emit Transfer(from: PancakePair: [0x3407c5398256cc242a7a22c373D9F252BaB37458],
to: 0x9D0d28f7b9a9e6D55abb9e41a87df133F316C68C,
value: 2446593118707)
This excerpt shows the core exploit cycle:
4349498877701 raw EHX units to the pair.0.001 BNB on swapExactETHForTokensSupportingFeeOnTransferTokens, routing the bought EHX to 0x000000000000000000000000000000000000dEaD.2446593118707 raw EHX units.The attacker therefore only loses 1902905758994 raw EHX units per loop while forcing a full 0.001 BNB treasury spend each time. Repeating that cycle 300 times drained approximately 0.300 BNB, and the final exit sale triggered one additional buyback for a total treasury loss of 0.301 BNB.
The balance diff confirms the treasury depletion and burn side effects:
{
"native_balance_deltas": [
{
"address": "0xe1747a23c44f445062078e3c528c9f4c28c50a51",
"delta_wei": "-301000000000000000"
}
],
"erc20_balance_deltas": [
{
"token": "0xe1747a23c44f445062078e3c528c9f4c28c50a51",
"holder": "0x000000000000000000000000000000000000dead",
"delta": "18466827989974706400"
}
]
}
That evidence matches the intended exploit effect exactly: native BNB leaves the EHX contract, while dead-address EHX balance increases due to forced buybacks. The price impact accumulates because each buyback adds WBNB to the pair and removes EHX from market circulation. Once the attacker had driven the pair to a sufficiently favorable state, they sold nearly the whole flash-loaned EHX position back into WBNB and exited.
The final trace segment shows the exit, repayment, and profit:
PancakePair::swap(5800154493083822263, 0, 0x9D0d28f7b9a9e6D55abb9e41a87df133F316C68C, 0x)
WBNB::transfer(0xFeAFe253802b77456B4627F8c2306a9CeBb5d681, 5589328092301986679)
WBNB::balanceOf(0x9D0d28f7b9a9e6D55abb9e41a87df133F316C68C) -> 210826400781835584
WBNB::transfer(0xddaaEDcf226729def824CC5c14382c5980844D1F, 210826400781835584)
The attacker received 5.800154493083822263 WBNB from the final sale, repaid 5.589328092301986679 WBNB to the DODO pool, and forwarded the remaining 0.210826400781835584 WBNB to the exploit EOA. After 0.078911457 BNB of gas spend, the net profit was 0.131914943781835584 BNB.
The adversary execution is a single-transaction ACT sequence with three on-chain stages:
Flash-loan funding
The EOA 0xddaaedcf226729def824cc5c14382c5980844d1f called helper contract 0x9d0d28f7b9a9e6d55abb9e41a87df133f316c68c, which borrowed 5.589328092301986679 WBNB from the public DODO pool 0xfeafe253802b77456b4627f8c2306a9cebb5d681.
Buyback spam and price ramp
The helper swapped the borrowed WBNB into EHX, then repeated 300 cycles of:
4349498877701 raw EHX units to the pair 0x3407c5398256cc242a7a22c373d9f252bab37458,_transfer() force a 0.001 BNB treasury buyback to the dead address,2446593118707 raw EHX units via the pair's public surplus handling.Exit and profit realization
After the pair price had been pushed up, the helper sold 13048.496062231756949226 EHX back into WBNB, repaid the original flash loan, and transferred the residual 0.210826400781835584 WBNB to the EOA.
The exploit worked because every step was permissionless:
skim() was public,The measurable protocol-side loss was the EHX treasury's native BNB depletion:
BNB: 301000000000000000 raw wei (0.301 BNB), decimal = 18Additional state impacts were material even though they are not recorded as the primary loss field:
18.4668279899747064 EHX from forced buybacks,0.208598435610846125 WBNB after the attacker's exit,0.131914943781835584 BNB net profit after gas.The affected public protocol components were the EHX token contract at 0xe1747a23c44f445062078e3c528c9f4c28c50a51 and the EHX/WBNB Pancake pair at 0x3407c5398256cc242a7a22c373d9f252bab37458.
0x8b528372b743b4b8c4eb0904c96529482653187c19e13afaa22f3ba4e08fbfbb on BSC block 335039120xe1747a23c44f445062078e3c528c9f4c28c50a51 (verified EHX source)0x3407c5398256cc242a7a22c373d9f252bab37458 (BscScan similar-match verified PancakePair)0xfeafe253802b77456b4627f8c2306a9cebb5d6810x10ed43c718714eb63d5aa57b78b54704e256024e-301000000000000000 wei on the EHX treasury and +18466827989974706400 EHX on the dead address/workspace/session/artifacts/auditor/iter_1/pair_verification_bscscan.txt