0xb06df371029456f2bf2d2edb732d1f3c8292d4271d362390961fdcc63a2382de0x2ff960f1d9af1a6368c2866f79080c1e0b253997BSC0xe70294c3d81ea914a883ad84fd80473c048c028cBSC0xb98f5322a91019311af43cf1d938ad0c59a6148aBSCOn BNB Chain block 44751945, transaction 0xb06df371029456f2bf2d2edb732d1f3c8292d4271d362390961fdcc63a2382de exploited LABUBU’s self-transfer bug to mint LABUBU inside a single transaction, drain nearly all VOVO from the LABUBU/VOVO PancakeSwap v3 pool, and exit through the VOVO/WBNB PancakeSwap v2 pair. The attacker’s EOA 0x27441c62dbe261fdf5e1feec7ed19cf6820d583b realized 17394034359323102166 wei net profit after gas. The root cause is LABUBU’s _transfer implementation: when sender == recipient, it writes the decremented balance and then overwrites the same slot with the pre-transfer balance plus amount, minting tokens instead of preserving balances.
LABUBU (0x2ff960f1d9af1a6368c2866f79080c1e0b253997) was listed as token0 in PancakeSwap v3 pool 0xe70294c3d81ea914a883ad84fd80473c048c028c, with VOVO (0x58b26c9b2d32df1d0e505bcca2d776698c9be6b6) as token1. That pool held 415636276381601458 LABUBU and 12608288158248437362131369009 VOVO immediately before the exploit. The attacker did not need privileged access: the transaction deployed fresh helper contracts, flash-borrowed LABUBU from the public v3 pool, used the inflated LABUBU to buy out VOVO liquidity, then sold the VOVO through the public VOVO/WBNB PancakeSwap v2 pair 0xb98f5322a91019311af43cf1d938ad0c59a6148a.
The incident is an ATTACK rooted in broken ERC20 balance conservation. LABUBU’s _transfer reads senderBalance and recipientBalance before writing either updated value. If sender and recipient are the same address, the code first stores senderBalance - amount and then overwrites that same storage slot with recipientBalance + amount, using the original pre-transfer value. The net result is a balance increase by amount on every self-transfer. Because PancakeSwap pools settle against token balances and assume listed tokens conserve value, the attacker could repay the flash loan with manufactured LABUBU and still retain enough inflated inventory to drain the paired real asset. The exploit was therefore permissionless, single-transaction, and deterministic once public LABUBU liquidity existed.
The verified LABUBU source shows the defect directly:
uint256 senderBalance = _balances[sender];
uint256 recipientBalance = _balances[recipient];
uint256 newSenderBalance = SafeMath.sub(senderBalance, amount);
if (newSenderBalance != senderBalance) {
_balances[sender] = newSenderBalance;
}
uint256 newRecipientBalance = recipientBalance.add(amount);
if (newRecipientBalance != recipientBalance) {
_balances[recipient] = newRecipientBalance;
}
When sender == recipient, both writes target the same storage slot. The second write uses the original recipientBalance, so the subtraction is discarded and the account balance increases by amount. The seed trace confirms the exploit path. First, the pool transferred 415636276381601458 LABUBU to helper 0x5cb78bf21ebaa3c44f4a1e8a3a3ee0041bb52a30. Inside the flash callback, the helper repeatedly called LABUBU::transfer to itself for that same amount, and the trace recorded the helper balance storage slot increasing on each self-transfer. The trace then shows the helper repaying 416675367072555462 LABUBU to the pool, swapping inflated LABUBU for 12608287525767706916530637084 VOVO, and later selling that VOVO for 17403082890323102166 wei WBNB. The balance diff independently confirms the state transition: the v3 pool lost 12608287525767706916530637084 VOVO, the v2 pair gained that exact VOVO amount, the helper retained 12023846439948514818 LABUBU after repayment, and the attacker EOA gained 17394034359323102166 wei net.
Representative trace excerpt:
emit Transfer(from: 0xe70294c3D81ea914A883ad84fD80473C048C028C, to: 0x5CB78bF21eBaa3C44f4A1E8A3a3Ee0041bb52a30, value: 415636276381601458)
LABUBU::transfer(0x5CB78bF21eBaa3C44f4A1E8A3a3Ee0041bb52a30, 415636276381601458)
storage slot helper_balance: 0x05c4...ceb2 -> 0x0b89...9d64
...
emit Transfer(from: 0xe70294c3D81ea914A883ad84fD80473C048C028C, to: 0x5CB78bF21eBaa3C44f4A1E8A3a3Ee0041bb52a30, value: 12608287525767706916530637084)
emit Transfer(from: 0x5CB78bF21eBaa3C44f4A1E8A3a3Ee0041bb52a30, to: 0xb98f5322a91019311af43cf1d938AD0c59A6148a, value: 12608287525767706916530637084)
emit Transfer(from: 0xb98f5322a91019311af43cf1d938AD0c59A6148a, to: PancakeRouter, value: 17403082890323102166)
The attacker EOA 0x27441c62dbe261fdf5e1feec7ed19cf6820d583b submitted a single transaction that first deployed orchestrator 0x2Ff0Cc42e513535BD56bE20c3E686A58608260CA and helper 0x5cb78bf21ebaa3c44f4a1e8a3a3ee0041bb52a30. The helper flash-borrowed the entire observable LABUBU inventory from the LABUBU/VOVO v3 pool. In the flash callback, it self-transferred the borrowed LABUBU repeatedly, inflating its balance until it could both repay the pool plus fee and still hold a large synthetic LABUBU balance. Next, it swapped inflated LABUBU against the same v3 pool to pull out almost all VOVO, leaving only 632480730445600731925 VOVO dust. Finally, it approved the PancakeSwap v2 router and sold all acquired VOVO into the VOVO/WBNB pair, routing native BNB proceeds back to the attacker EOA. No private keys, privileged methods, or attacker-specific on-chain artifacts were required beyond fresh contracts deployed in the exploit transaction.
The measurable loss was the extraction of value from the LABUBU/VOVO market and its conversion into WBNB. The balance diff shows a gross outflow of 17403082890323102166 wei WBNB from the VOVO/WBNB pair and a net gain of 17394034359323102166 wei at the attacker EOA after gas. The LABUBU/VOVO v3 pool lost 12608287525767706916530637084 VOVO and was left with only 632480730445600731925 VOVO. The helper contract also retained 12023846439948514818 LABUBU after repaying the flash loan, which is direct evidence that LABUBU was minted by self-transfer rather than sourced from market inventory.
0xb06df371029456f2bf2d2edb732d1f3c8292d4271d362390961fdcc63a2382de0x2ff960f1d9af1a6368c2866f79080c1e0b253997, especially _transfer in Contract.sol lines 119-1400xe70294c3d81ea914a883ad84fd80473c048c028c0xb98f5322a91019311af43cf1d938ad0c59a6148a