Calculated from recorded token losses using historical USD prices at the incident time.
0xfe031685d84f3bae1785f5b2bd0ed480b87815c3f23ce6ced73b8573b7e367c60x17bd2e09fa4585c15749f40bb32a6e3db58522baBSCOn BSC block 37400485, tx 0xfe031685d84f3bae1785f5b2bd0ed480b87815c3f23ce6ced73b8573b7e367c6 let an unprivileged attacker force Ethernal Finance II's buyback and then sell into the protocol-funded price move. The exploit was permissionless: the attacker used a flash loan, created enough dust holders to satisfy the buyback threshold, called the public doBuyback() function, sold ETHFINII after the protocol's own purchase raised price, repaid the flash loan, and kept profit.
The root cause is that Ethernal Finance II treats every first-time positive recipient as a new holder and exposes doBuyback() publicly with only that spoofable holder count as its gate. The treasury spend was therefore attacker-timed rather than protocol-controlled.
Ethernal Finance II (0x17bd2e09fa4585c15749f40bb32a6e3db58522ba) is a taxed token with several internal BNB pots. One of those pots, BuybackPotBNB, funds buyback-and-burn operations. The contract tracks holder growth through N_holders and schedules the next buyback via NextBuybackMemberCount.
Two design details matter:
function transfer(address _to, uint _value) public override returns (bool success) {
require(_value > 0 && _value <= balanceOf(msg.sender));
UpdateRegister(_to, false);
_transferWithTax(msg.sender, _to, _value);
return true;
}
function UpdateRegister(address recipient, bool ExcludedfromTax) private {
if (_isregistered[recipient] == false) {
investorList.push(recipient);
_isregistered[recipient] = true;
_LastPayout[recipient] = block.timestamp;
if (!isContract(recipient)) _AutoPayoutEnabled[recipient] = true;
N_holders++;
_excludedfromTax[recipient] = ExcludedfromTax;
_SplitTokenRewards[recipient] = true;
}
}
Every first-time recipient increments N_holders, regardless of whether the transfer is economically meaningful. For non-sell transfers, buy tax is amount / 10, so a 1 wei transfer pays zero integer-divided tax while still creating a new holder entry.
The vulnerability is an attacker-manipulable treasury trigger. Ethernal Finance II uses N_holders as the sole condition for when buyback funds may be spent, but N_holders is not a robust measure of organic adoption. It can be increased by sending trivial token dust to fresh addresses. Because transfer() calls UpdateRegister() before the taxed transfer path completes, any positive transfer to a new address creates a new holder record. Because doBuyback() is public, any actor can immediately spend treasury funds once the spoofed threshold is crossed. That lets an attacker decide both timing and market context for the buyback. The exploit becomes profitable when the buyback pot is large enough to move the ETHFINII/WBNB market price and the attacker accumulates ETHFINII before triggering the protocol purchase.
Immediately before the exploit transaction, the reconstructible public state showed N_holders = 8222, NextBuybackMemberCount = 8616, and a funded buyback pot. The attacker contract also had a negligible pre-existing ETHFINII balance, which is consistent with the attack's need to distribute dust before the threshold-crossing call.
The victim-side breakpoint is the combination of UpdateRegister() and doBuyback():
function doBuyback() public returns (bool) {
if ((_isLaunched == true) && (N_holders >= NextBuybackMemberCount)) {
uint256 amountBNB = BuybackPotBNB * 40 / 100;
BuybackPotBNB -= amountBNB;
...
emit Buyback_(tokens, N_holders);
NextBuybackMemberCount = NextBuybackMemberCount + Buyback_increment;
Buyback_increment = Buyback_increment * 110 / 100;
return true;
}
}
The exploit transaction used that logic in three stages:
12 WBNB.395 one-wei ETHFINII transfers to fresh recipients, taking N_holders from 8222 to 8617.doBuyback(), which spent treasury BNB to buy and burn ETHFINII, raising price and enabling the attacker to sell into the move.The trace-backed post-state confirms the trigger fired exactly as the analysis claims. In the validator PoC run, the same semantic outcomes appear on a fork: N_holders ends at 8617, NextBuybackMemberCount advances to 9614, and the attack path exits with profit. The historical balance diff also shows the protocol treasury losing 2631482115268895179 wei BNB while the attacker EOA gains 2021229382260447344 wei BNB after fees.
The attacker cluster consists of EOA 0x52e38d496f8d712394d5ed55e4d4cdd21f1957de and exploit contract 0x11bfd986299bb0d5666536e361f312198e882642. The EOA submitted the transaction and received the final native-asset profit. The contract executed the on-chain sequence.
The execution flow was:
Flash-loan WBNB
-> inflate N_holders with dust ETHFINII transfers
-> accumulate ETHFINII inventory
-> call public doBuyback()
-> sell ETHFINII after protocol-induced pump
-> repay flash loan
-> withdraw residual WBNB as BNB profit
The exploit is ACT because every required action used public, permissionless infrastructure: Pancake liquidity pools, a public flash-loan source, public token transfers, and a public victim function. No privileged role, private key, or private orderflow was required.
The direct treasury loss was the forced buyback spend from the victim contract:
BNB: "2631482115268895179" raw weiThat treasury spend was not a benign internal accounting move. It was converted into an attacker-timed market purchase that the attacker immediately monetized. The attacker EOA's balance diff shows a net gain of 2021229382260447344 wei BNB after transaction fees, while the victim contract's native balance dropped by 2631482115268895179 wei.
0xfe031685d84f3bae1785f5b2bd0ed480b87815c3f23ce6ced73b8573b7e367c60x17bd2e09fa4585c15749f40bb32a6e3db58522baartifacts/collector/seed/56/0x17bd2e09fa4585c15749f40bb32a6e3db58522ba/src/Contract.solartifacts/collector/seed/56/0xfe031685d84f3bae1785f5b2bd0ed480b87815c3f23ce6ced73b8573b7e367c6/trace.cast.logartifacts/collector/seed/56/0xfe031685d84f3bae1785f5b2bd0ed480b87815c3f23ce6ced73b8573b7e367c6/balance_diff.json