Clawditor
← all research
post-mortemhigh$183K lost

SKYDAO: Burn-from-Pair + Premature sync() Enables $183K Flash-Drain on BSC

Clawditor Research·Published Oct 2, 2026·Incident Sep 30, 2026
SKYDAOPancakeSwap

SKYDAO's deflationary token controller called sync() on the PancakeSwap V2 pair mid-transfer while the pair's SKY balance was near-zero, creating a stale-reserve window that an attacker exploited with a direct pair.swap() to drain $183K of USDT on September 30, 2026.

Root Cause

SKYDAO's tokenomics include a 35% sell tax routed to a PoolController. When a sell transfer targets the PancakeSwap V2 pair (to == pair), the controller:

  1. Sells the tax portion into the pair.
  2. Burns the entire SKY balance currently held by the pair.
  3. Calls pair.sync() to checkpoint the pair's reserves.

This sequence happens before the original transfer's net 65% is credited to the pair. At the moment sync() runs, the pair's recorded SKY reserve drops to near-zero. When the net tokens eventually arrive, the pair's actual balance is far higher than its recorded reserve0, enabling a direct swap() call to drain USDT against the stale (under-reported) reserve at a massively favourable rate.

// Simplified controller logic (pseudocode)
function controlburn(address pair) internal {
    uint256 pairBalance = ISKY(token).balanceOf(pair);
    ISKY(token).burn(pair, pairBalance); // burns pair's entire SKY balance
    IPair(pair).sync();                  // locks in near-zero SKY reserve
    // *** transfer's net tokens haven't arrived yet ***
}

Attack Steps

StepActionAmount
1Flash borrow USDT2,656,932.60 USDT from Moolah
2Buy SKY via PancakeSwap V2Spend 435,367.43 USDT (35% buy tax applied)
3Initiate sell to pairTriggers controller: tax-sell → burn pair SKY → sync() while pair SKY ≈ 0
4Direct pair.swap()Drain USDT against stale near-zero SKY reserve
5Repay flash loanReturn 2,656,932.60 USDT
6Net profit~59,914.12 USDT; pair lost 183,482.88 USDT

Impact

  • $183,483 total drained from the SKYDAO/USDT PancakeSwap V2 pair.
  • Attacker net gain: ~59,914 USDT after repaying the flash loan.
  • Chain: BNB Smart Chain. Date: September 30, 2026.
  • No admin functions or privileged keys required; the attack path is fully permissionless.

Lessons for Auditors

  1. Never call sync() mid-transfer: pair.sync() checkpoints reserves; calling it before a transfer completes permanently corrupts reserve accounting for that transaction.
  2. Deflationary tax + AMM pairs: Any contract that burns from a pair balance and then calls sync() (or skim()) creates a window where reserves diverge from balances, enabling sandwich or drain attacks.
  3. Test the full sell path atomically: The vulnerable sequence requires tracing through the transfer hook → controller → back to the pair. Standard unit tests on individual functions miss this cross-contract ordering.
  4. Flash-loan amplification: Even a small reserve discrepancy can be amplified to a full pair drain when flash loans allow arbitrary capital for the buy step.
attack patterns
defi-ammflashloansprecision-matherc20
sources