Calculated from recorded token losses using historical USD prices at the incident time.
0x4f2005e3815c15d1a9abd8588dd1464769a00414a6b7adcbfd75a5331d378e1d0xB3e708a6d1221ed7C58B88622FDBeE2c03e4DB4dBSC0x46ba8a59f4863bd20a066fd985b163235425b5f9BSCThe exploit transaction 0x4f2005e3815c15d1a9abd8588dd1464769a00414a6b7adcbfd75a5331d378e1d drained the WDOGE/WBNB PancakePair on BSC by abusing WDOGE's reflection-tax transfer logic. A flash-loan-funded attacker bought WDOGE, repeatedly transferred taxed WDOGE into the pair, recovered the resulting excess WDOGE with skim, fixed the manipulated balance into reserves with sync, and then sold against the inflated pair-side WDOGE balance to withdraw nearly all WBNB.
The root cause is that WDOGE mutates holder balances during taxed transfers and does not exclude the AMM pair from redistribution. PancakePair swap accounting assumes its balances change only through explicit swap inputs and outputs. Once WDOGE credits the pair during attacker-controlled transfers, the pair observes fictitious WDOGE input and releases excess WBNB.
The victim pair is 0xB3e708a6d1221ed7C58B88622FDBeE2c03e4DB4d, with token0 = WDOGE and token1 = WBNB. Immediately before the exploit, the pair held 7102767012379398034561708289684 WDOGE and 78658352619485714640 wei of WBNB. The exploit used the public DODO flash-loan pool 0x0fe261aee0d1c4dfddee4102e82dd425999065f4 to borrow 2900 WBNB in a single transaction.
WDOGE is a taxed reflection token. Outside its initial opening window, each transfer burns 4%, redistributes 4%, and routes 2% to fee wallets. The redistribution mechanism iterates over the tracked holder list and directly increments each holder's internal balance. Because the pair is a tracked holder, it receives extra WDOGE during taxed transfers and that balance mutation is visible to PancakePair.
The vulnerability is an AMM-compatibility failure in a reflection token. In WDOGE, the taxed branch of _transfer calculates burn, redistribution, and fee slices, credits the recipient with only the post-tax amount, and then calls redistribute(sender, tokensToRedistribute). Inside redistribute, the contract loops over _balanceOwners and increments each tracked holder balance other than the sender. That list includes the PancakePair address once it has ever received tokens.
This breaks the pair's accounting invariant: the pair's observed WDOGE balance no longer equals explicit trader input minus explicit output over the swap accounting window. An attacker can therefore transfer WDOGE to the pair, let redistribution add even more WDOGE to the pair, reclaim the excess with skim, checkpoint the manipulated state with sync, and finally drain WBNB by making PancakePair treat redistributed balance growth as real input. The exploit is permissionless because it requires only public liquidity, public contracts, and an attacker-deployed helper contract.
The critical victim code is the taxed path in WDOGE:
function _transfer(address sender, address recipient, uint256 amount) internal virtual returns (bool) {
...
uint256 tokensToBurn = onePercent * 4;
uint256 tokensToRedistribute = onePercent * 4;
...
_balances[recipient].amount += tokensToTransfer;
...
if (!_balances[recipient].exists) {
_balanceOwners.push(recipient);
_balances[recipient].exists = true;
}
redistribute(sender, tokensToRedistribute);
_burn(sender, tokensToBurn);
}
function redistribute(address sender, uint256 amount) internal {
for (uint256 i = 0; i < _balanceOwners.length; i++) {
if (_balances[_balanceOwners[i]].amount == 0 || _balanceOwners[i] == sender) continue;
...
_balances[_balanceOwners[i]].amount += toReceive;
}
}
This code directly increases the balances of tracked holders, including the pair, during an unrelated transfer. The incident happened long after closingTime = 1623002400, so the taxed branch was active at block 17248706. As a result, every attacker transfer of WDOGE into the pair both moved net tokens to the pair and redistributed additional WDOGE to the pair and other holders.
The seed trace shows the exploit path end to end. The attacker helper contract first borrowed 2900 WBNB from the public DODO pool. It then transferred that WBNB into the pair and called swap(6638066501837822413045167240755, 0, attacker, 0x) to buy WDOGE. After becoming a WDOGE holder, the attacker sent 5532718068557297916520398869451 WDOGE to the pair, called skim(attacker), then sync(), and then sent 4466647961091568568393910837883 WDOGE to the pair. Those steps are visible in the trace immediately before the final draining swap.
The last critical step is the pair withdrawal. The trace records swap(0, 2978658352619485704640, attacker, 0x), which transfers out almost all WBNB and leaves the pair with exactly 10000 wei. The same transaction repays the 2900 WBNB flash loan and transfers the remaining 78658352619485704640 wei of WBNB profit to 0xBDf77C7eaea4369A448163589ED463443E593cF8. The gas-paying sender EOA spent 28031114700000000 wei in native BNB according to the balance diff.
The exploit was executed by sender EOA 0x962f8b446de3e524cf99042149ebecc0130bcdbf through helper contract 0x614a198523aee53b420fd20d0c97481226c4ce85, with profit forwarded to 0xBDf77C7eaea4369A448163589ED463443E593cF8.
First, the helper contract took a public flash loan of 2900 WBNB from 0x0fe261aee0d1c4dfddee4102e82dd425999065f4. Second, it transferred that WBNB to the WDOGE/WBNB pair and swapped out a very large WDOGE amount, which made the attacker helper a tracked WDOGE holder eligible for redistribution. Third, it performed two taxed recycle transfers into the pair, using skim after the first transfer to recover excess pair-side WDOGE and sync to commit manipulated balances into reserves before the second transfer. Finally, it drained WBNB with the inflated-balance swap, repaid the flash loan inside the same transaction, and transferred the remaining WBNB to the beneficiary EOA.
Representative trace events:
flashLoan(2900 WBNB, ..., attacker, 0x31)
swap(6638066501837822413045167240755, 0, attacker, 0x)
skim(attacker)
sync()
swap(0, 2978658352619485704640, attacker, 0x)
transfer(flash loan repayment: 2900 WBNB)
transfer(profit to beneficiary: 78658352619485704640 wei WBNB)
The measurable loss was 78658352619485704640 wei of WBNB, or 78.658352619485704640 WBNB, extracted from the WDOGE/WBNB PancakePair. After the drain, the pair retained only 10000 wei of WBNB dust. The exploit was fully permissionless and reproducible by any actor able to borrow temporary WBNB liquidity and submit the same public call sequence.
0x4f2005e3815c15d1a9abd8588dd1464769a00414a6b7adcbfd75a5331d378e1d on BSC.0x46ba8a59f4863bd20a066fd985b163235425b5f9.0xB3e708a6d1221ed7C58B88622FDBeE2c03e4DB4d._transfer and redistribute.flashLoan, swap, skim, sync, repayment, and profit transfer.