We do not have a reliable USD price for the recorded assets yet.
0xea88dc6dbd81d09c572b5849e0d4508598edcf8f11c9a995cd8fe7e6c194f39e0xf662457774bb0729028ea681bb2c001790999999BSC0x389a9ae29fbe53cca7bc8b7a4d9d0a04078e1c24BSCOn BSC block 38230509, transaction 0xea88dc6dbd81d09c572b5849e0d4508598edcf8f11c9a995cd8fe7e6c194f39e exploited a public helper at 0x389a9ae29fbe53cca7bc8b7a4d9d0a04078e1c24 to drain BNBX from users who had already approved that helper as a spender. The attacker EOA 0x123fa25c574bb3158ecf6515595932a92a1da510 deployed a fresh batching contract 0xe6e06030b33593d140f224fc1cdd1b8ffe99e50a, invoked selector 0x11834d4c repeatedly against approved holders, then sold the stolen BNBX into the live BNBX/WBNB Pancake pair 0xAa3f145f854e12F1566548c01e74c1b9d98c634d.
The root cause is an unrestricted allowance-consumption helper. The runtime for selector 0x11834d4c reads the token from storage slot 0x0b, queries balanceOf(holder), then executes transferFrom(holder, CALLER, balance) with no caller authorization. Because BNBX uses standard ERC20 allowance checks, any unprivileged caller could sweep balances from holders that had already approved the helper.
BNBX at 0xf662457774bb0729028ea681bb2c001790999999 follows a standard ERC20 transferFrom path. Its verified source shows transferFrom calls _spendAllowance(from, spender, amount) before , so a third party can only move a holder's tokens if that holder already approved the spender contract.
_transferThe vulnerable contract was not the token itself. It was the public helper 0x389a9ae29fbe53cca7bc8b7a4d9d0a04078e1c24, which many holders had approved. Once approved, the helper's selector 0x11834d4c exposed a permissionless sweep primitive over those allowances.
The monetization path was also public. The BNBX/WBNB Pancake pair 0xAa3f145f854e12F1566548c01e74c1b9d98c634d and router 0x10ED43C718714eb63d5aA57B78B54704E256024E already had live liquidity, so drained BNBX could immediately be converted to WBNB.
This incident is an ATTACK-class ACT opportunity caused by broken helper logic, not by privileged access or a token-side accounting flaw. The violated invariant is straightforward: a spender helper may consume an allowance only for the holder-authorized recipient flow, not for an arbitrary external caller that chooses itself as recipient.
The code-level breakpoint is the runtime body behind selector 0x11834d4c in 0x389a.... The disassembly excerpt shows the function loading the token address from slot 0x0b, calling balanceOf(holder), then calling transferFrom(holder, CALLER, balance). No owner check, signature check, or recipient binding appears before the CALLER value is forwarded as the recipient.
That behavior becomes exploitable because BNBX itself behaves normally. Its verified source proves the token still enforces the allowance relation, so the helper contract was the actual unsafe component: it transformed a legitimate allowance into a permissionless public sweep. Any searcher observing holders with positive BNBX balances and approvals to 0x389a... could drain those balances and sell the proceeds.
The ACT pre-state existed immediately before block 38230509. At that point, the helper contract had BNBX configured in storage slot 0x0b, multiple users had nonzero BNBX balances and approvals to the helper, and the Pancake BNBX/WBNB pair had sufficient liquidity for immediate monetization.
The critical helper behavior is captured in the disassembly excerpt:
00000c49: PUSH1 0x0b
00000c4b: SLOAD
...
00000c4f: PUSH4 0x70a08231
...
00000cb5: PUSH1 0x0b
00000cb7: SLOAD
...
00000cc4: PUSH4 0x23b872dd
00000cc9: DUP4
00000cca: CALLER
...
Interpretation:
- slot 0x0b stores the token address
- the function calls token.balanceOf(holder)
- the function calls token.transferFrom(holder, caller, balanceOf(holder))
The token-side evidence independently confirms this is an allowance-consumption exploit:
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
The seed trace for 0xea88dc6d... then shows the exploit using that primitive exactly as expected. The attacker-created helper 0xe6e06030b33593d140f224fc1cdd1b8ffe99e50a repeatedly calls 0x389a...::11834d4c(...), and each call triggers a BNBX transferFrom(holder, 0xe6e06030..., amount) event. Later in the same transaction, the accumulated BNBX is sold through Pancake, producing a final pair swap that sends 75467165324636766463 WBNB to attacker EOA 0x123fa25c574bb3158ecf6515595932a92a1da510.
This makes the exploit permissionless and deterministic. The attacker did not need private keys for any victim, protocol admin privileges, or a special contract deployment already on chain. The only prerequisites were public state: approved holder addresses, positive BNBX balances, and live DEX liquidity.
The adversary flow was a single transaction with three clear stages.
First, EOA 0x123fa25c574bb3158ecf6515595932a92a1da510 submitted tx 0xea88dc6dbd81d09c572b5849e0d4508598edcf8f11c9a995cd8fe7e6c194f39e and created contract 0xe6e06030b33593d140f224fc1cdd1b8ffe99e50a. The metadata artifact ties the EOA to the transaction origin and shows the batching contract being created inside that transaction.
Second, the new contract iterated through pre-approved holders and called selector 0x11834d4c on 0x389a.... The trace shows repeated lines of the form:
0x389A...::11834d4c(holder)
BNBX::transferFrom(holder, 0xe6e06030B33593d140f224fc1cdd1b8fFe99E50a, amount)
emit Transfer(from: holder, to: 0xe6e06030..., value: amount)
The balance-diff artifact corroborates the effect at scale: many holder balances on BNBX fall from positive amounts to zero in the same transaction. The root cause is therefore not hypothetical; the exploit trace shows the exact primitive being exercised against real approved holders.
Third, after aggregating the stolen BNBX, the batching contract swapped it for WBNB using the live Pancake pair and routed the proceeds to the attacker EOA. The trace ends with a pair swap emitting amount0Out: 75467165324636766463 WBNB to 0x123fa25c574bb3158ecf6515595932a92a1da510, while the balance diff records the EOA paying 9932136000000000 wei in gas. The profit predicate is therefore directly observed on chain.
The measurable token loss recorded in the analysis is 858063371727740547599841 BNBX base units, with 18 decimals. This reflects the aggregate BNBX drained from approved holders in the exploit transaction.
The attacker's realized proceeds were 75.467165324636766463 WBNB, while gas cost was 0.009932136 BNB. In practical terms, users who had approved 0x389a... were exposed to full-balance drains, and the attacker converted the stolen inventory into immediately spendable WBNB through Pancake liquidity.
0xea88dc6dbd81d09c572b5849e0d4508598edcf8f11c9a995cd8fe7e6c194f39e0x389a9ae29fbe53cca7bc8b7a4d9d0a04078e1c240x123fa25c574bb3158ecf6515595932a92a1da5100xe6e06030b33593d140f224fc1cdd1b8ffe99e50a0xf662457774bb0729028ea681bb2c0017909999990x10ED43C718714eb63d5aA57B78B54704E256024E0xAa3f145f854e12F1566548c01e74c1b9d98c634d0x11834d4c disassembly excerpt collected in the session artifacts.