SwapX Arbitrary transferFrom Approval Drain on BNB Chain
Exploit Transactions
Victim Addresses
0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01BSCLoss Breakdown
Similar Incidents
SwapX Stale-Allowance Drain
49%MetaPoint Public Approval Drain
38%SellToken Arbitrary-Pair LP Drain
37%BNB-chain constructor exploit drains full USDT pool balance
36%GGGTOKEN Treasury Drain via receive()
34%Sheep Burn Reserve Drain
34%Root Cause Analysis
SwapX Arbitrary transferFrom Approval Drain on BNB Chain
1. Incident Overview TL;DR
Immediately before exploit block 26023089, the pre-state at block 26023088 already exposed an ACT opportunity: public BUSD allowances from many holders to 0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01, thin DND/WBNB liquidity on Biswap, and public liquidity to acquire DND inventory on Pancake. The adversary first bought 1,000,000 DND in tx 0xf3a5d378a7c5184a75f8a1783733ce5816836ef716c4d56214439e25ec744e75, then executed tx 0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160 to force 59 approved BUSD holders through a BUSD -> WBNB -> DND route on Biswap and finally dump the attacker inventory for 739.641476234907877084 WBNB.
The root cause is a public arbitrary-from spend primitive in the unverified SwapX-style helper at 0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01. Its selector 0x4f1f05bc accepts a caller-supplied victim address and forwards that address into ERC20 transferFrom without binding the source account to msg.sender and without any signature or permit for the current execution. Because BUSD correctly keys allowance on the spender contract address, any external caller could spend historical approvals granted to the helper and route the stolen BUSD through a price-manipulating path.
2. Key Background
0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01 is an unverified public swap helper. Its runtime contains both owner-only branches and a separate public swap selector path. The exploit did not depend on privileged ownership of that helper or on any private attacker artifact; it depended only on publicly visible approvals and public DEX liquidity.
BUSD at 0xe9e7cea3dedca5984780bafc599bd69add087d56 behaves like a standard allowance-based token. Its verified source shows that transferFrom spends _allowances[sender][_msgSender()], so once the vulnerable helper nominates itself as the spender and supplies an arbitrary sender, the token cannot distinguish whether the helper is acting for the real holder or for an unrelated external caller.
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));
return true;
}
Snippet origin: verified BUSD token source code.
The DND inventory also came from public liquidity. The auditor identified tx 0xf3a5d378a7c5184a75f8a1783733ce5816836ef716c4d56214439e25ec744e75 as a permissionless Pancake buy that acquired exactly 1000000000000000000000000 raw DND for 0.058145203030945085 BNB. The exploit sequence then used public Biswap liquidity at router 0x3a6d8ca21d1cf76f653a67577fa0d27453350dd8 and the thin DND/WBNB pair 0xa6c26b72d76a7bcf663c7a1146cad6bc4cd6157f.
3. Vulnerability Analysis & Root Cause Summary
This incident is an ATTACK, not a benign MEV opportunity. The violated invariant is straightforward: a public swap contract may only spend ERC20 balances from msg.sender or from an address that has explicitly authorized the current caller for the current swap execution. The vulnerable helper breaks that invariant because its public selector 0x4f1f05bc decodes a caller-controlled source address and routes that address into a downstream transferFrom.
The runtime evidence is direct. Selector 0x4f1f05bc is publicly dispatched, and after calldata decoding the control flow jumps into the public swap path at offset 0x0304 instead of an owner gate. Later, helper code at offset 0x40bd builds an ERC20 call with selector 0x23b872dd, which is transferFrom(address,address,uint256).
00000050: PUSH4 0x4f1f05bc
00000055: EQ
00000056: PUSH2 0x008b
...
00000154: CALLDATALOAD
0000015e: PUSH2 0x0304
00000161: JUMP
...
000040bd: JUMPDEST
...
00004102: PUSH4 0x23b872dd
00004107: PUSH1 0xe0
00004109: SHL
0000410a: OR
Snippet origin: disassembly of the live runtime code at 0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01.
The consequence is that any external caller can iterate over holders that approved the helper, drain as much BUSD as their balance and allowance permit, and choose a route that benefits the attacker economically. Here the route was specifically chosen to force buys into thin DND liquidity on Biswap, then monetize the induced price spike by selling an attacker-owned DND inventory. The root cause therefore combines an access-control failure in allowance consumption with an economically exploitable route choice.
4. Detailed Root Cause Analysis
The ACT opportunity pre-state sigma_B is fully public and reconstructible immediately before tx 0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160: the vulnerable helper is deployed, public BUSD approvals to it are visible on-chain, the Biswap DND/WBNB pool is live, and Pancake liquidity is sufficient to buy the attacker's initial DND inventory. No private key, signature leak, or attacker-only calldata is needed.
The exploit path starts when the wrapper contract calls selector 0x4f1f05bc on the vulnerable helper and provides:
- a token route
[BUSD, WBNB, DND], - a per-victim spend amount,
- a distribution array,
- and a caller-selected victim address.
The seed trace shows the helper performing exactly that flow for drained holders. One representative call is below:
0x6D8981847Eb3cc2234179d0F0e72F6b6b2421a01::4f1f05bc(..., 0x4741f74bd551f060939507f544e6c149f2f88a8b, ...)
BEP20Token::transferFrom(
0x4741f74BD551F060939507f544e6c149f2f88a8B,
BiswapPair: [0xaCAac9311b0096E04Dfe96b6D87dec867d3883Dc],
1844054995956188306206
)
Snippet origin: exploit execution trace for tx 0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160.
That trace line is the concrete safety breakpoint. The caller is the attacker wrapper, but the token transfer source is a third-party holder address. Because BUSD only checks whether spender 0x6d898... has allowance from the holder, the call succeeds even though the holder did not authorize this specific execution path.
The seed balance diff confirms that the exploit operated at scale. Exactly 59 holders show negative BUSD deltas, and their aggregate loss equals the BUSD increase on Biswap pair 0xacaac9311b0096e04dfe96b6d87dec867d3883dc:
- aggregate drained BUSD:
230359800545335337795174raw units, - pair BUSD increase:
230359800545335337795174raw units.
The drained holder set reconstructed from the validated root-cause artifact is:
0x0b70e2abe6f1a056e23658aed1ff9ef9901cb2a3
0x210c9e1d9e0572da30b2b8b9ca57e5e380528534
0x6906f738dafd4bf14d6e3e979d4aaf980ff5392d
0x708a34d4c5a7d7fd39ee4db0593be18df58fd227
0x48ba64b8cbd8bbce086e8e8ecc6f4de34aa35d08
0x29cb2eaf6b9b12a17c708d6246911f6893bc6d4e
0x4148b0b927cc8246f65af9b77dfa84b60565820c
0x047252b87fb7ecb7e29f8026dd117eb8b8e6cf0f
0x08943873222ce63ec48f8907757928dcb06af388
0x8c51b7bb3f64845912616914455517df294a0d0b
0x91243b8242f13299c5af661ef5d19bfe0d3bf024
0xfe23ea0cec98d54a677f4ad3082d64f8a0207eb7
0x54d7afcaf140fa45ff5387f0f2954bc913c0796f
0x76bf18afed5accfd59525d10ce15c4b8cb64370d
0xe5d985b7b934dc0e0e1043fc11f50ba9e229465c
0xcbc33e060badcaec95d0654492e2a926a79ba652
0xb756969197362a04dba44debdf53fb18a38aa9b4
0x578bc4667a2099e24521b6e59796038d357771e9
0xb98c81843ac4f407cb8c3be8f542a03a6c4102a1
0x976eccac4c7642ec1699efac6e626dea5a60ae1a
0x1b5708c2b2192fa3ea9ee1ef1494205d3851cbcb
0xffc1b7c0eac19a511c89e2f299a039f1b93d11c1
0x2dbc97fafd68396bf4bec82b89aa8e78af2e3077
0xba67d444dc27884b5b0e58939916ef47a8887233
0x63f12a794778691c97d408bbb468fde160e0b2ab
0x524b9806c5d4eb6fec8b53f2368f8f3d730735c2
0xba55b08ce677a9b053b9f428532493c93f520372
0x1e803f8bf93243ac36175600707150976e001320
0xca7e7ce232787ca373ad4ffbbf4d782bba40edca
0xf868234a4039d595329e0faa48c42b32136abd94
0xf8cfa024eb9da2bd4e4312da1b97b56596467f5c
0xc7691091ba8853a0e174c31402d339be9ee9f1ac
0xe63cdcdb22d01ec60ca833452d6c09ca49938de5
0xe212c1330a24c4151ca142f8e0da778303ca2b2e
0x13b18d21c5362c225dab49b2f49f55742fde049e
0x1eef8a09c8fba4d7fc8001850c0e53e64d70deba
0x42238feb30ddb3991c57ae74af2f05f26cf41139
0x6e720cec5fb7348c9c5b676febd6d3a3d65dc19e
0xd34e06b8c17a41d2135c6d23ed4cb015eac2bf89
0x115134e731fe81d38bd0803f8ecbe5c9027624d0
0xa29406b74cdc8e94e0941311a6deb2bb30b245ae
0xcfe07c466ff76e1e006c1ef696812269e1bc34d0
0x7e5a4d4168b9c778a0d29a53c3b4fd8e0ba514f7
0x93f27e2d44b56d996c0b8064d5bfc54a62c03c5d
0x1ac037d994fab808be5f965a3fea630b3c72ab4b
0x057d0fa0946eceae0bedd711b69d6808df6db676
0x6066b41a17b01c578327da8371270484fcb87bdf
0x846d72b9e7b5f5dafe6758e24d4f35734b0db1f8
0xd36ac079bb7966a585cb541332946fa57c6e29c0
0xfbdc6ddf8a9affd61936297ad57da393af3cb1b6
0xaa1c48c84bc33bc82987690a3b526bd02a715160
0x4741f74bd551f060939507f544e6c149f2f88a8b
0xcce314df2f3826bbcaa3315ecdd4552394151c90
0x58d0b5cb7da447aa02013b1e91ebbdcd733dd686
0xbff7d0e68d28926faba562812dfa5e8321c01059
0xc2a441bd22532990ece484374e400f6910404ee9
0xd34b6dd79c88179c1694010ca66364324d1d3f44
0x3a3421f7d6c7a6c51f514db6afa497421f585bf6
0x5795f44f01c353eca8f4a3000751796d3472f2fc
The exploit only becomes profitable because the drained BUSD is not simply stolen as BUSD. Instead, it is routed through Biswap to buy DND, which raises the DND/WBNB exchange rate just long enough for the attacker to exit an independently acquired inventory. The trace confirms the exit leg:
0x3a6d8cA21D1CF76F653A67577FA0D27453350dD8::swapExactTokensForTokens(
1000000000000000000000000,
739641476234907877084,
[DND, WBNB],
0xc4beA60F5644B20eBb4576E34d84854f9588A7E2,
1677479141
)
...
WBNB::transfer(0xc4beA60F5644B20eBb4576E34d84854f9588A7E2, 739641476234907877084)
Snippet origin: exploit execution trace for the final dump leg in tx 0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160.
5. Adversary Flow Analysis
The adversary strategy summary is: buy cheap DND on Pancake, use the public arbitrary-from spend path to force victim BUSD into DND buys on Biswap, then dump the attacker inventory into the resulting price spike.
The adversary-related cluster is:
- EOA
0x7d192fa3a48c307100c3e663050291fff786aa1f: bought the DND inventory, deployed the wrapper, funded it, and submitted the exploit sequence. - Contract
0xc4bea60f5644b20ebb4576e34d84854f9588a7e2: attacker-deployed wrapper that held1,000,000 DNDbefore the exploit and received the final WBNB proceeds.
The victim-side candidates identified in the validated artifact are:
- Unverified vulnerable helper
0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01. - Verified Biswap DND/WBNB pair
0xa6c26b72d76a7bcf663c7a1146cad6bc4cd6157f. - The 59 drained BUSD holders listed above.
The end-to-end lifecycle is:
- Inventory acquisition. In tx
0xf3a5d378a7c5184a75f8a1783733ce5816836ef716c4d56214439e25ec744e75, the attacker permissionlessly acquired1,000,000 DNDfor0.058145203030945085 BNB. - Wrapper preparation. In tx
0xb5d77b5a3298a2cde04458e0d465e6846b71d6e47a23d2ae0b340a5e6d497098, the attacker deployed wrapper0xc4bea60f5644b20ebb4576e34d84854f9588a7e2. In tx0x88173528bde29268a0d9f5b2a4894166d63227d07e71c231cd3715605c9966f5, the attacker transferred the full1,000,000 DNDinventory into that wrapper. - Approval drain and price-manipulated exit. In tx
0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160, the wrapper iterated over67candidates, successfully drained59, forced those balances into DND buys, and sold the wrapper's full inventory for739.641476234907877084 WBNB.
This sequence satisfies the ACT framing because every step is realizable by any unprivileged actor using canonical on-chain data and public infrastructure. The observed attacker used a wrapper contract, but the exploit primitive itself already exists in the public helper and does not require the observed wrapper bytecode or attacker identities.
6. Impact & Losses
The directly measured loss is:
BUSD:230359800545335337795174raw units (230359.800545335337795174 BUSD,18decimals).
The attack forcibly converted 59 holders from BUSD into DND through a route they did not authorize. The non-monetary exploit predicate is therefore also satisfied: third-party holders who only approved 0x6d898... as a spender lost BUSD and received DND without authorizing the attacker-controlled execution. Economically, the attacker transformed that forced flow into 739.641476234907877084 WBNB and a net reference-asset delta of 739.522352351876931999 BNB after the 0.060978680 BNB cost basis and fees captured in the root-cause artifact.
7. References
- Exploit tx:
https://bscscan.com/tx/0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160 - Attacker DND inventory buy:
https://bscscan.com/tx/0xf3a5d378a7c5184a75f8a1783733ce5816836ef716c4d56214439e25ec744e75 - Vulnerable helper address:
https://bscscan.com/address/0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01 - Contract-creation evidence for
0x6d898...and0xc4bea...:https://api.etherscan.io/v2/api?chainid=56&module=contract&action=getcontractcreation&contractaddresses=0x6d8981847eb3cc2234179d0f0e72f6b6b2421a01,0xc4bea60f5644b20ebb4576e34d84854f9588a7e2 - Collector metadata:
/workspace/session/artifacts/collector/seed/56/0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160/metadata.json - Collector trace:
/workspace/session/artifacts/collector/seed/56/0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160/trace.cast.log - Collector balance diff:
/workspace/session/artifacts/collector/seed/56/0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160/balance_diff.json - Verified BUSD source code:
/workspace/session/artifacts/collector/seed/56/0xe9e7cea3dedca5984780bafc599bd69add087d56/src/Contract.sol - Relevant transactions and roles from the validated root-cause artifact:
0xf3a5d378a7c5184a75f8a1783733ce5816836ef716c4d56214439e25ec744e75(adversary-crafted)0xb5d77b5a3298a2cde04458e0d465e6846b71d6e47a23d2ae0b340a5e6d497098(related)0x88173528bde29268a0d9f5b2a4894166d63227d07e71c231cd3715605c9966f5(related)0x3ee23c1585474eaa4f976313cafbc09461abb781d263547c8397788c68a00160(seed)