Eterna Buyback Treasury Drain
Exploit Transactions
0x8b528372b743b4b8c4eb0904c96529482653187c19e13afaa22f3ba4e08fbfbbVictim Addresses
0xe1747a23c44f445062078e3c528c9f4c28c50a51BSC0x3407c5398256cc242a7a22c373d9f252bab37458BSCLoss Breakdown
Similar Incidents
GGGTOKEN Treasury Drain via receive()
44%Public Treasury Spend on BRAND Helper
39%BCT Referral Treasury Drain
38%CCV Treasury Rebalancer Attack
38%Matmo MAMO Treasury Drain
38%CS Pair Balance Burn Drain
36%Root Cause Analysis
Eterna Buyback Treasury Drain
1. Incident Overview TL;DR
On 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.
2. Key Background
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
);
}
3. Vulnerability Analysis & Root Cause Summary
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.
4. Detailed Root Cause Analysis
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:
- The attacker sends
4349498877701raw EHX units to the pair. - Because the sender is not an AMM pair and the treasury is funded, EHX immediately spends
0.001BNB onswapExactETHForTokensSupportingFeeOnTransferTokens, routing the bought EHX to0x000000000000000000000000000000000000dEaD. - The attacker then uses the pair's permissionless excess-balance handling to recover
2446593118707raw 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.
5. Adversary Flow Analysis
The adversary execution is a single-transaction ACT sequence with three on-chain stages:
-
Flash-loan funding The EOA
0xddaaedcf226729def824cc5c14382c5980844d1fcalled helper contract0x9d0d28f7b9a9e6d55abb9e41a87df133f316c68c, which borrowed5.589328092301986679WBNB from the public DODO pool0xfeafe253802b77456b4627f8c2306a9cebb5d681. -
Buyback spam and price ramp The helper swapped the borrowed WBNB into EHX, then repeated
300cycles of:- transfer
4349498877701raw EHX units to the pair0x3407c5398256cc242a7a22c373d9f252bab37458, - let EHX's
_transfer()force a0.001BNB treasury buyback to the dead address, - recover
2446593118707raw EHX units via the pair's public surplus handling.
- transfer
-
Exit and profit realization After the pair price had been pushed up, the helper sold
13048.496062231756949226EHX back into WBNB, repaid the original flash loan, and transferred the residual0.210826400781835584WBNB to the EOA.
The exploit worked because every step was permissionless:
- the flash-loan pool was public,
- the Pancake router and pair were public,
- the EHX trigger condition depended only on sender type and treasury balance,
skim()was public,- and the attacker did not need any real attacker-side artifact beyond a fresh helper contract to bundle the calls.
6. Impact & Losses
The measurable protocol-side loss was the EHX treasury's native BNB depletion:
BNB:301000000000000000raw wei (0.301BNB),decimal = 18
Additional state impacts were material even though they are not recorded as the primary loss field:
- the dead address received
18.4668279899747064EHX from forced buybacks, - the EHX/WBNB pair's WBNB reserve was driven down to
0.208598435610846125WBNB after the attacker's exit, - and the attacker realized
0.131914943781835584BNB net profit after gas.
The affected public protocol components were the EHX token contract at 0xe1747a23c44f445062078e3c528c9f4c28c50a51 and the EHX/WBNB Pancake pair at 0x3407c5398256cc242a7a22c373d9f252bab37458.
7. References
- Seed exploit transaction:
0x8b528372b743b4b8c4eb0904c96529482653187c19e13afaa22f3ba4e08fbfbbon BSC block33503912 - Victim token contract:
0xe1747a23c44f445062078e3c528c9f4c28c50a51(verified EHX source) - Exploited Pancake pair:
0x3407c5398256cc242a7a22c373d9f252bab37458(BscScan similar-match verified PancakePair) - Public flash-loan pool:
0xfeafe253802b77456b4627f8c2306a9cebb5d681 - Public router used in the flow:
0x10ed43c718714eb63d5aa57b78b54704e256024e - Validator evidence set:
- collected tx metadata for the seed transaction
- opcode-level seed trace showing flash-loan funding, dust loops, final sale, repayment, and profit transfer
- balance-diff artifact showing
-301000000000000000wei on the EHX treasury and+18466827989974706400EHX on the dead address - auditor-added BscScan verification evidence for the pair at
/workspace/session/artifacts/auditor/iter_1/pair_verification_bscscan.txt