# SKP token: owner-armed transfer hook drains USDT pair

SKP token's _transfer hook redistributed unbounded treasury SKP to an owner-whitelisted address when pair balance exceeded reserves, drained via flash-loan-inflated buy.

- Payout: Real-world hack
- Severity: critical
- Program: SKP Token
- Credited: DeFiHackLabs
- Disclosed: 2026-05-26
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-05/SKP_exp2.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260526-skp-exp2
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:flash-loan

**Target:** BEP-20 token _transfer hook on PancakeSwap V2 pair
**Root cause:** SKP._transfer fires _runSpecialPairFlow when from==pair, computing excess = balanceOf(pair) - reserve and transferring an unbounded treasury amount to a single owner-set whitelist address; the trigger is flash-loan inflatable and the K-check ignores the free tokens.
**Steps:**
1. Fork BSC at block 100,582,078; pair 0x47C8... reserves ~234,135 USDT / ~21,574,109 SKP
2. Obtain ~204,950,260 USDT (on-chain: aggregated from 9 flash-loan sources via BlockRazor private relay)
3. `USDT.approve(ROUTER, max)` then `swapExactTokensForTokensSupportingFeeOnTransferTokens(204950260e18, 0, [USDT,SKP], WL_ADDRESS, deadline)`
4. Router transfers USDT to pair, calls `pair.swap(0, ~21,546,000 SKP, WL_ADDRESS, 0x)`
5. SKP._transfer(from=PAIR,to=WL) triggers _runSpecialPairFlow: excess=204,950,260 > threshold, transfers ~9,678,739,566 treasury SKP to WL_ADDRESS
6. pair.sync() inside hook reverts on reentrancy lock and is silently caught; K-check passes on original trade only
7. Sell redistributed SKP back to USDT for ~$212k profit
**How found:** On-chain forensics: WL_ADDRESS set by onlyOwner 6 days before drain, WL creator == SKP deployer, unverified source, pre-configured private relay/bridge, 7+ throwaway tokens, dust-airdrop-inflated holder count, ~14-day lifecycle — indicating an insider rug pull disguised as a contract vulnerability.
**Exploitation:** Operator set WL_ADDRESS via onlyOwner setFeeWhiteList ~6 days prior, deployed/funded WL from same wallet as SKP deployer, left source unverified, pre-configured BlockRazor private mempool and deBridge. Attacker flash-loaned ~$205M USDT, bought SKP with WL_ADDRESS as recipient to trigger the hook's unbounded treasury redistribution, then sold the free SKP for ~$212,195 USDT.
**Escalation:** Flash-loan aggregation across 9 sources inflated pair balance to maximize the excess and thus the treasury redistribution amount in a single tx.
**Insight:** When auditing token transfer hooks, check whether any branch computes an amount from live balanceOf(pair) minus cached reserve — that delta is flash-loan inflatable in one tx and bypasses the AMM K-check since free minted tokens never enter the swap accounting.
