Public Treasury Spend on BRAND Helper
Exploit Transactions
0x19ef4febcd272643642925d5d7e9ab8fd3ed8785c5e3268f5b6fee44ae6b4a34Victim Addresses
0x831d6f9aa6af85cead4ccec9b859c64421eeefd4BSCLoss Breakdown
Similar Incidents
EEECOIN Public Helper LP Drain
41%CCV Treasury Rebalancer Attack
39%Eterna Buyback Treasury Drain
39%ARA Swap Helper Approved-Holder Exploit
38%GymRouter Arbitrary Approved Token Spend
38%Matmo MAMO Treasury Drain
38%Root Cause Analysis
Public Treasury Spend on BRAND Helper
1. Incident Overview TL;DR
On BSC transaction 0x19ef4febcd272643642925d5d7e9ab8fd3ed8785c5e3268f5b6fee44ae6b4a34 in block 33139125, attacker EOA 0x835b45d38cbdccf99e609436ff38e31ac05bc502 used exploit contract 0xf994f331409327425098feecfc15db7fabf782b7 to flash-borrow 300 WBNB, buy BRAND, force helper contract 0x831d6f9aa6af85cead4ccec9b859c64421eeefd4 to execute 25 unauthorized buyToken() calls, and then sell the pre-positioned BRAND back into WBNB. The helper contract spent exactly 25 BNB of its own treasury and the attacker realized 23.181868108667834716 WBNB gross profit, or 23.174558764667834716 BNB net after 0.007309344 BNB gas.
The root cause is a direct access-control failure in the unverified helper contract, not in PancakeSwap or BrandPad. Administrative functions are owner-gated, but the treasury-moving functions buyToken(), sellToken(), and exec() are public. Any unprivileged caller can therefore force the helper to trade with its own assets whenever it holds spendable BNB or the configured token.
2. Key Background
The primary victim component is the unverified helper contract at 0x831d6f9aa6af85cead4ccec9b859c64421eeefd4. Independent state reads at block 33139124 show that it was owned by 0x70547a2ce4def7175c69421d7221f62992c81a58, held 25.31562237105995358 BNB, and had transactionAmount() configured to 1 BNB per trade. The configured token was BRAND at 0x4d993ec7b44276615bb2f6f20361ab34fbf0ec49, traded through Pancake router 0x10ED43C718714eb63d5aA57B78B54704E256024E and pair 0x0040890a6a33674db2dd706462398503b6ab7078.
BrandPad is a reflection token, so raw storage deltas on _rOwned are not the user-facing token balance. Its verified source shows that balanceOf() converts reflected balances through tokenFromReflection, which is why the correct victim BRAND balance must be read through the token interface:
function balanceOf(address account) external view override returns (uint256) {
if (_isExcluded[account]) return _tOwned[account];
return tokenFromReflection(_rOwned[account]);
}
That matters here because the victim helper started with 0 BRAND at block 33139124 and ended with 37082833697629 BRAND at block 33139125, even though the raw storage delta in the token contract is represented in reflected units.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability class is an ATTACK-type access-control failure. The helper contract clearly separates administrative functions from trading functions, but only the administrative paths enforce authorization. Disassembly shows a shared owner-check helper at offset 0x1119 that compares msg.sender against the owner stored in slot 0, and owner-only entries such as withdrawStuckToken(address), withdrawNativeToken(), updateTokenAddress(address), updateRouter(address), and transferOwnership(address) all jump through that helper before moving funds or mutating configuration. In contrast, buyToken() at 0x0c10, sellToken() at 0x085b, and exec() at 0x0f7f are publicly reachable and do not invoke 0x1119 before spending treasury assets. buyToken() reads the router from slot 1, the configured token from slot 2, and the fixed trade amount from slot 3, then performs Pancake router selector 0xb6f9de95 (swapExactETHForTokensSupportingFeeOnTransferTokens) with the helper contract’s own BNB. This breaks the core invariant that only the owner or an explicitly authorized actor should be able to spend the helper contract treasury.
4. Detailed Root Cause Analysis
The owner-gated path is visible directly in the helper bytecode. For example, the administrative entries jump into the owner-check helper at 0x1119, and that helper reverts when msg.sender is not the stored owner:
0000034f: JUMPDEST
00000350: PUSH2 0x0357
00000353: PUSH2 0x1119
00000356: JUMP
...
00000616: JUMPDEST
00000617: PUSH2 0x061e
0000061a: PUSH2 0x1119
0000061d: JUMP
...
00001093: JUMPDEST
00001094: PUSH2 0x109b
00001097: PUSH2 0x1119
0000109a: JUMP
...
00001119: JUMPDEST
00001138: PUSH2 0x113f
0000113b: PUSH2 0x0832
0000113e: JUMP
00001156: EQ
00001157: PUSH2 0x119e
0000115a: JUMPI
The vulnerable trading path omits that authorization check. buyToken() starts at 0x0c10, constructs the swap path, loads the configured trade amount from slot 3, and calls the router with value:
00000c10: JUMPDEST
...
00000de8: PUSH4 0xb6f9de95
00000ded: PUSH1 0x03
00000def: SLOAD
...
00000df3: ADDRESS
00000df4: TIMESTAMP
...
00000e2e: GAS
00000e2f: CALL
The incident transaction realizes that defect exactly once end-to-end. The attacker exploit contract first borrowed 300 WBNB from DODO, swapped it into BRAND, and then repeatedly invoked the helper’s public buyToken() entry point. The collected trace shows the sequence clearly:
0x6098A5638d8D7e9Ed2f952d35B2b67c34EC6B476::flashLoan(300000000000000000000, 0, 0xf994f331409327425098FeEcFc15db7faBf782B7, 0xa4821719)
PancakeRouter::swapExactTokensForTokensSupportingFeeOnTransferTokens(300000000000000000000, 0, [WBNB, BRAND], 0xf994f331409327425098FeEcFc15db7faBf782B7, 1698921681)
0x831d6F9AA6AF85CeAD4ccEc9B859c64421EEeFD4::buyToken() [25 times]
PancakeRouter::swapExactTokensForTokensSupportingFeeOnTransferTokens(2978374964504432, 0, [BRAND, WBNB], 0xf994f331409327425098FeEcFc15db7faBf782B7, 1698921681)
WBNB::transfer(0x835B45D38cbDccf99E609436FF38E31Ac05bc502, 23181868108667834716)
The helper’s native balance moved from 25315622371059953580 wei to 315622371059953580 wei, a precise 25 BNB loss. The attacker did not own the helper contract, yet every buyToken() call succeeded, proving that the authorization bypass is the concrete code-level breakpoint. The attack works whenever the helper holds treasury funds and the configured token has enough AMM liquidity for the attacker to enter before the victim-funded buys and exit afterward.
5. Adversary Flow Analysis
The adversary cluster consists of EOA 0x835b45d38cbdccf99e609436ff38e31ac05bc502 and exploit contract 0xf994f331409327425098feecfc15db7fabf782b7. The EOA signed the incident transaction and received the final profit. The exploit contract handled the flash loan, swaps, repeated victim calls, repayment, and final payout.
The on-chain flow is:
- The exploit contract borrows
300 WBNBfrom DODO pool0x6098a5638d8d7e9ed2f952d35b2b67c34ec6b476. - It buys
2978374964504432 BRANDthrough PancakeSwap, creating a long position before the helper starts buying. - It calls the helper’s public
buyToken()exactly25times. Each call spends the helper’s fixed1 BNBtrade amount and sends the acquiredBRANDback to the helper itself. - After the victim-funded buys move the price upward, the exploit contract sells its original
BRANDinventory for323.181868108667834716 WBNB. - It repays the
300 WBNBflash loan and transfers the remaining23.181868108667834716 WBNBto the attacker EOA.
This is an ACT opportunity because no privileged access is required. The attacker only needs public state: the helper’s BNB balance, the configured token and router, the fixed trade amount, and the live Pancake reserves.
6. Impact & Losses
The direct victim loss is 25 BNB, encoded on-chain as "25000000000000000000" with 18 decimals. The helper contract was drained from 25.31562237105995358 BNB to 0.31562237105995358 BNB and left holding 37082833697629 BRAND. The attacker received 23.181868108667834716 WBNB gross profit and paid 0.007309344 BNB in gas, for 23.174558764667834716 BNB net economic gain. The affected public components are the helper contract 0x831d6f9aa6af85cead4ccec9b859c64421eeefd4, BrandPad token 0x4d993ec7b44276615bb2f6f20361ab34fbf0ec49, and the Pancake BRAND/WBNB pair 0x0040890a6a33674db2dd706462398503b6ab7078.
7. References
- Incident transaction:
0x19ef4febcd272643642925d5d7e9ab8fd3ed8785c5e3268f5b6fee44ae6b4a34on BSC block33139125. - Victim helper contract:
0x831d6f9aa6af85cead4ccec9b859c64421eeefd4. - Attacker EOA:
0x835b45d38cbdccf99e609436ff38e31ac05bc502. - Attacker exploit contract:
0xf994f331409327425098feecfc15db7fabf782b7. - Supporting evidence: seed tx metadata, verbose seed trace, balance-diff artifact, and supplemental disassembly/state observations collected for this session.
- Verified source used for contextual interpretation: BrandPad token
0x4d993ec7b44276615bb2f6f20361ab34fbf0ec49.