Calculated from recorded token losses using historical USD prices at the incident time.
0x0d13a61e9dc81cfae324d3d80e49830d9bbae300f760e016a15600889a896a1b0xa2b8a15a07385ea933088c6bcbb38b84c1051a58BSC0x3921e8cb14e2c08db989fdf88d01220a0c53cc91BSCOn BSC transaction 0x0d13a61e9dc81cfae324d3d80e49830d9bbae300f760e016a15600889a896a1b at block 33053188, an unprivileged attacker used a public DODO WBNB flash loan to buy LaEeb, repeatedly transferred LaEeb directly into the LaEeb/WBNB Pancake pair at 0x3921e8cb14e2c08db989fdf88d01220a0c53cc91, and immediately recovered the same tokens with PancakePair::skim. Those pseudo-sells repeatedly exercised LaEeb's sell-side maintenance logic until the LaEeb token contract at 0xa2b8a15a07385ea933088c6bcbb38b84c1051a58 accumulated enough native BNB to execute a 4 BNB dead-wallet buyback. The attacker then dumped LaEeb back into the pair, repaid the flash loan, and realized a net sender-level gain of 218451604933465601 wei in BNB/WBNB after gas.
The root cause is a logic bug in LaEeb's sell-maintenance path. AmountCountDeadBNB is incremented when dead-fee tokens are converted to BNB, but it is never decremented after LaEeb spends 4 BNB on the dead-wallet buyback. Because LaEeb also treats any plain token transfer to the pair as a sell, and PancakePair lets a caller reclaim excess pair balances with skim, an unprivileged attacker can repeatedly trigger the buyback path without surrendering the triggering inventory.
LaEeb is a fee-on-transfer token that routes sell-side fees through internal maintenance functions before finalizing a user transfer whenever the recipient is marked as an automated market maker pair. The relevant pair is the LaEeb/WBNB Pancake pair at 0x3921e8cb14e2c08db989fdf88d01220a0c53cc91.
Two system behaviors make the exploit possible:
reserve0 and reserve1 unchanged until swap, mint, burn, or sync.automatedMarketMakerPairs[to], so a plain transfer into the pair executes the same maintenance logic that a real AMM sale would execute.At the exploitable pre-state, block 33053187, the public values were already primed in the attacker's favor:
AmountCountDeadBNB = 78558676974458564672AmountDeadBNB = 40000000000000000003572802069843452599That means the stale counter was already above the 4 BNB threshold, while the treasury still needed to be pushed above 4 BNB for the buyback branch to fire.
This incident is an ATTACK case caused by broken budget accounting inside LaEeb. The token tracks BNB generated from dead-fee conversions in AmountCountDeadBNB, but it does not consume that budget when it later spends 4 BNB on swapETHForTokensToAddress(..., deadWallet). As a result, the same recorded budget can authorize repeated dead-wallet buybacks.
The exploit is reachable because LaEeb equates any transfer into the pair with a sell. That lets an attacker trigger the sell-maintenance path using a plain token transfer instead of an irrevocable router sale. The paired PancakePair contract then returns the excess transferred tokens through skim, so the attacker can recycle nearly the same LaEeb inventory across many trigger iterations.
The safety invariant is straightforward: a counter representing accumulated buyback budget must decrease when the budget is spent, and treasury-spending logic should only run on transfers that correspond to a real swap input. LaEeb violates both conditions. The concrete breakpoint is the _transfer branch that spends AmountDeadBNB without reducing AmountCountDeadBNB.
The verified LaEeb source shows the sell-maintenance branch in _transfer:
if (
canSwap &&
!swapping &&
automatedMarketMakerPairs[to] &&
from != owner() &&
to != owner() &&
bbswapAndLiquifyEnabled &&
from != address(this)
) {
swapping = true;
if (address(this).balance >= AmountDeadBNB && AmountCountDeadBNB >= AmountDeadBNB) {
swapETHForTokensToAddress(AmountDeadBNB, deadWallet);
}
if (AmountDeadFee >= (100 * (10**18)) && balanceOf(address(this)) >= AmountDeadFee) {
swapTokensForEthXH(AmountDeadFee);
}
...
swapping = false;
}
The verified helper that accumulates the budget is separate:
function swapTokensForEthXH(uint256 tokenAmount) private {
uint256 initialBalance = address(this).balance;
swapTokensForEth(tokenAmount);
uint256 newBalance = address(this).balance.sub(initialBalance);
AmountCountDeadBNB = AmountCountDeadBNB.add(newBalance);
AmountDeadFee = AmountDeadFee.sub(tokenAmount);
}
The missing operation is the bug: after the buyback spends 4 BNB, LaEeb never subtracts 4 BNB from AmountCountDeadBNB. Once the counter exceeds the threshold, it remains reusable.
The verified PancakePair source supplies the second half of the exploit:
function skim(address to) external lock {
address _token0 = token0;
address _token1 = token1;
_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
}
Because a plain LaEeb transfer into the pair does not update reserves, skim returns the excess LaEeb immediately. The attacker can therefore:
skim to recover the excess LaEeb from the pair.The seed trace confirms that exact sequence. It shows repeated alternation between direct LaEeb-to-pair transfers and PancakePair::skim(0x0c96d5...), then the treasury-spending call:
PancakePair::skim(0x0c96d5A27f20a838b778caD29e111cbAeF85923a)
...
PancakeRouter::swapExactETHForTokensSupportingFeeOnTransferTokens{value: 4000000000000000000}(
0,
[WBNB, LaEeb],
0x000000000000000000000000000000000000dEaD,
...
)
The public pre-state snapshot explains why the loop only needed to top up treasury BNB rather than prime the counter from zero. Before the incident transaction, AmountCountDeadBNB was already 78558676974458564672, while the treasury held only 3572802069843452599 wei. The attack therefore consumed an already stale authorization.
The adversary cluster consists of:
0x7cb74265e3e2d2b707122bf45aea66137c6c88910x9180981034364f683ea25bcce0cff5e03a595bef0x0c96d5a27f20a838b778cad29e111cbaef85923aThe trace-backed flow is:
33053188, tx index 0.8672889958749180735 WBNB from DODO pool 0xfeafe253802b77456b4627f8c2306a9cebb5d681.72361332796676237007449844673667 LaEeb units after buy fees.skim, forcing LaEeb's sell-maintenance functions to run while recovering the transferred inventory.69524768551046528516757810762566 LaEeb units back to WBNB for 10416184159661589796 WBNB.1743294200912409061 WBNB to the sender.The final profit derivation is deterministic. The sender started with:
1547532469017576990232218475368782335436156971722270540034459After the transaction, the sender held:
1532284043057787555633961769569694744497157190173875473500060The net sender-level reference-asset gain was therefore 218451604933465601 wei after paying 1524842595978943460 wei in gas. The helper and orchestrator return to their pre-state WBNB balances, so this sender-level delta equals the adversary-cluster delta.
The directly measured victim-side loss in the incident transaction is native BNB drained from the LaEeb token contract:
3502602582368107367 weiThe balance diff also shows a corresponding dead-wallet token inflow:
15405738501967291893024884551459 LaEeb unitsFrom the attacker's perspective, the economically relevant result is the net increase in sender reference-asset value:
218451604933465601 weiThe loss is localized to the LaEeb treasury and the forced dead-wallet purchase path. No privileged access, private keys, or attacker-only infrastructure were required; the opportunity was fully permissionless.
0x0d13a61e9dc81cfae324d3d80e49830d9bbae300f760e016a15600889a896a1b0xa2b8a15a07385ea933088c6bcbb38b84c1051a580x3921e8cb14e2c08db989fdf88d01220a0c53cc9133053187