Dedaub · Transaction Triage / BNB Smart Chain

LEAF token drained via fee-accounting skim

A flash-loan–funded economic exploit that bled the LEAF token contract's own reserves into its PancakeSwap pool, then skimmed the difference as USDT.

tx 0xfe3e0ac89a0ca4f26e9158b801475cd5140649fd8825c4987494008abea1a99f · block 111,489,571 · 2026-07-22
HACK · CONFIRMED

Yes — this is a hack.An attacker with zero starting capital extracted ~$1,627 of USDT by abusing LEAF's transfer-triggered fee logic. Not a normal deposit, swap, or protocol operation.

Attacker profit
+1,628.42 USDT
Value drained from LEAF
2,011.6 LEAF
Flash loan used
26,200 USDT
Attacker's own capital
0
Chain / block
BSC · 111,489,571
Tx status
Success

Executive summary 01

The transaction is a contract deployment (to = null) sent by EOA 0x1ef4…d3ab. The deployed contract borrows USDT via a Moolah flash loan and, inside the loan callback, repeatedly triggers a side effect in the LEAF token's transfer logic. Each trigger moves LEAF out of the token contract's own balance into the LEAF/USDT PancakeSwap pair. The attacker then unwinds the inflated pool position back into USDT, repays the loan, and keeps the surplus.

Net result: the attacker EOA gains 1,628.42 USDT having supplied no capital; the LEAF/USDT pair loses exactly that much USDT; and the LEAF token contract is drained of 2,011.6 LEAF of its held reserves. This is the signature of an economic exploit, not legitimate activity.

How the attack worked 02

  1. 1

    Deploy & pre-approve

    The tx deploys attacker contract 0xc77D…3F66, which spawns a helper 0x70e3…17f7 and a sub-contract 0xa5e6…98d4, then grants unlimited USDT/LEAF approvals to the PancakeSwap router and the Moolah lender.

  2. 2

    Flash-loan 26,200 USDT from Moolah

    rescue(26200e18, 12600e18, 200)flashLoan(USDT, 26,200) on the Moolah proxy. Execution enters the onMoolahFlashLoan callback with the borrowed USDT in hand.

  3. 3

    Seed the pool: swap + add liquidity

    Sends 12,600 USDT into the LEAF/USDT pair, swaps for ~10,238 LEAF, then addLiquidity of ~13,600 USDT + ~10,136 LEAF — establishing an LP position it controls.

  4. 4

    200× zero-value transfers — the exploit

    Fires transferFrom(pair, helper, 0) on LEAF 200 times (the 200 arg to rescue). A transfer from the pair routes into _handleBuy → _distributeBonus(), which fires regardless of amount and flushes a fixed MIN_FEE_POOL (~10 LEAF) tranche of the contract's own balance to LDX bonus recipients — the pool chief among them. ~200 × 10 ≈ 2,011 LEAF, all for free.

  5. 5

    Unwind & convert to USDT

    Removes liquidity (burn), sweeps the sub-contract, then swapExactTokensForTokensSupportingFeeOnTransferTokens dumps ~11,713 LEAF back into the now–LEAF-rich pair for USDT.

  6. 6

    Repay loan, pocket the difference

    Repays the 26,200 USDT to Moolah and transfers the 1,628.42 USDT surplus to the attacker EOA.

Net value changes 03

AddressRoleAssetNet Δ
0x1ef4…d3abattacker EOAUSDT+1,628.42 (+$1,627)
0xa4d6…3d08LEAF/USDT pairUSDT−1,628.42 (−$1,627)
0xa4d6…3d08LEAF/USDT pairLEAF+1,475.53
0x386b…0b01LEAF token (victim)LEAF−2,011.60
0x0000…deadburnLEAF+203.74
0xc2d5…850bLEAF fee walletLEAF+332.34

The 2,011.60 LEAF lost by the token contract lands as +1,475.53 (pair) + 203.74 (burn) + 332.34 (fee wallet) — the fee/burn split its own transfer logic applies. USD is current CoinGecko spot, approximate for a historical block.

Root cause 04

Missing require(amount > 0) guard on the bonus payout

Confirmed against the verified source (LEAFToken, solc 0.8.34). _transfer has no early-out for amount == 0; its only check is balanceOf(from) >= amount, which 0 >= 0 passes. When the sender is the LP pair, control reaches _handleBuy, which calls _distributeBonus() before touching amount. That function flushes one fixed MIN_FEE_POOL (~10 LEAF) tranche of the contract's own balance to registered LDX bonus recipients on every call. With no zero-amount guard anywhere, transferFrom(pair, …, 0) triggers this payout for free, unbounded — draining the fee pool one tranche at a time.

This belongs to a well-documented family of BSC incidents — fee / burn "skim" attacks funded by Moolah flash loans (see references).

// LEAFToken (verified, solc 0.8.34) — the unguarded side effect
function _handleBuy(address from, address to, uint256 amount) internal {
    _distributeBonus();              // fires even when amount == 0
    uint256 burnAmount  = amount / 100;    // 0 when amount == 0
    uint256 finalAmount = amount * 99 / 100;
    ...
}
function _distributeBonus() internal {
    if (feePool < MIN_FEE_POOL) return;    // ~10 LEAF per call...
    uint256 share = minLpAmount[user] * MIN_FEE_POOL / totalStaked;
    feePool -= share;
    super._transfer(address(this), user, share);  // contract's OWN LEAF out
}
// attacker loop: 200 × transferFrom(pair, helper, 0)  →  ~2,011 LEAF drained

Actors & contracts 05

AddressRoleNotes
0x1ef40356631d8449dadf4e2fac6389b5d7e7d3abattacker EOADeployer & profit recipient
0xc77D9d6FBF52a8503Bf6Df3A904d27f478533F66attack contractDeployed by this tx
0x70e35ac23345039a68a184e2f7f6249d7a2217f7helperRuns rescue / flash-loan callback
0x386bf5d829a8e24311120bebec1d7aec32930b01LEAF tokenVictim — vulnerable transfer logic
0xa4d604e6f888e4796e086a9762af9ff412a83d08LEAF/USDT pairPancakeSwap V2 pool drained of USDT
0x8f73b65b4caaf64fba2af91cc5d4a2a1318e5d8cMoolah lenderFlash-loan source (26,200 USDT)
0x55d398326f99059ff775485246999027b3197955USDT (BSC)Borrowed & stolen asset
0x10ed43c718714eb63d5aa57b78b54704e256024ePancakeSwap routerSwaps & liquidity ops

References — same exploit class 06

Prepared with the Dedaub EVM transaction triager. Trace via debug_traceTransaction (callTracer); value flows are complete and independent of trace expansion.

USD figures are current CoinGecko spot and approximate for a historical block. No public incident report was found for this specific tx at time of writing — the classification rests on the on-chain evidence above.