BNB Chain
Reserve manipulation

BYToken's $88.1K Loss and How Olympix Would Have Prevented It

Loss
Loss
Exploit date
June 4, 2026

At 20:38:09 UTC on June 4, 2026, an attack contract on BNB Chain sold a single wei of BY, the smallest unit the token has, into the BY/WBNB pool on PancakeSwap and received 38,543.31 WBNB for it. It did the same thing four more times. By then the pool's BY balance had been burned down so far that dust traded like a fortune, and by the end of the transaction the pool had paid out 146.60 WBNB more than it took in, about $88,100 at the time.

The burn that set this up came from BY's own contract. According to SlowMist's incident record, BY exposed a maintenance function called triggerAutoBurn() that anyone could call, and it burned BY straight out of the pool and then forced the pool to sync its reserves. TenArmor flagged the attack on X the same evening and put the loss at about $88.4K.

A Housekeeping Function Anyone Could Run

Plenty of tokens on BNB Chain ship with automatic burn mechanics meant to shrink supply over time, and many of them burn from the token's own liquidity pool so the price of the remaining supply rises. In a PancakeSwap V2 pair, the pool's price lives in two stored reserve numbers, and sync() rewrites them to match the balances the pool actually holds. Burn tokens out of the pair and call sync(), and the pool's BY reserve falls while its WBNB reserve stays put, which makes every remaining BY worth more WBNB.

A function with that kind of power over a market belongs to the team that runs it, called on a schedule they control and in amounts they choose. SlowMist describes triggerAutoBurn() as public, so the timing of the burn, and with it the moment the pool's reserves changed, belonged to whoever called it. BY's source code isn't verified on-chain, so the function's exact logic can't be read from an explorer, and the account here rests on SlowMist's summary and the transfers recorded in the transaction.

One Transaction, Four Hundred Thousand Borrowed WBNB

The attacker's wallet, 0x0475...0bad, called an attack contract at 0xc081...85ec. That contract flash-borrowed 422,497.06 WBNB, then traded heavily against the BY/WBNB pair, putting in 7,098.44 WBNB in one swap and another 69,938.18 WBNB across two more while taking BY out. SlowMist reports that the burn came next, removing a large amount of BY from the pool and syncing its reserves, which left the pool with a tiny BY reserve sitting on top of all the WBNB the attacker had just pushed in.

What followed shows how far the reserves had moved. The attack contract sent 1 wei of BY to the pair five times, and each time the pool released WBNB: 38,543.31, then 12,858.49, then 6,433.26, then 3,861.89, then 2,575.67. A final sale of 62,868 BY brought out another 12,910.61 WBNB. Added up, the pool paid out 77,183.24 WBNB against the 77,036.62 WBNB the attacker had put in, a net 146.60 WBNB taken from the pool's liquidity providers.

The contract repaid the full 422,497.06 WBNB flash loan in the same transaction and unwrapped the 146.60 WBNB it kept into BNB. SlowMist lists the incident under smart contract vulnerabilities with a loss of $87,402, and TenArmor's alert said about $88.4K, two valuations of the same 146.60 WBNB. As of November 6, 2026, we couldn't find a statement or post-mortem from the BY team.

The Mistake Was in Who Could Pull the Lever

Burning from a pool is risky on its own, because it changes the pool's price without anyone trading. Making it permissionless turns that price change into something an outsider can schedule. An attacker who controls when the burn lands can line it up with their own trades, push the pool into the shape that makes the burn most damaging, and sell into the result before anyone else can react.

Burns that come out of a pair and end in sync() have a track record on BNB Chain, and in March a version of the same mechanic, with sellers steering the size of the burn, drained BCE Token's $800K pool.

How Olympix Would Have Caught the Open Trigger

Olympix reads a contract the way an attacker does, as states, transitions and entry points, and it takes in the context around the code to infer the rules the system depends on. For BY, the state that matters most belongs to the PancakeSwap pair, its BY balance and the reserves it records after sync(), and every entry point that can change them is a path worth mapping. The engine narrows from all paths to the feasible ones, and then to the ones that touch an invariant, using signals to decide where to look first.

Olympix's static analysis would have surfaced the signal in BY's code: an external function with no access restriction that burns tokens from the pair's address and then calls sync() on the pair. Missing access control on a function that moves a market's reserves is the kind of finding that puts a path at the front of the queue.

The invariant fits in a sentence: the pool's BY reserve should only fall when someone pays the pool for the BY that leaves, and no outside caller should be able to change the pool's price without trading against it. BugPoCer would have run Counterexample-Guided Invariant Refutation, working outward from the token and its pair as one system and executing call sequences until one broke that rule. A single call to triggerAutoBurn() from an arbitrary address would already have broken it, and BugPoCer would then have extended the sequence until the broken reserve paid out WBNB.

What would have come back is a counterexample: trade against the pair, call the public burn, sell dust into the distorted reserves, and collect WBNB. BugPoCer would have returned that sequence with the minimal conditions that trigger it and a generated Forge test that replays it, which is the June 4 drain produced in development, where adding an owner check to one function would have closed it. Olympix runs at every merge and before release, so a public burn trigger wired to the pool would have been tested the day it was added.

Keep the Burn Lever Behind a Lock

BY's automatic burn could have been a harmless supply mechanic with an owner check and a burn source that wasn't the pool. Any function that changes a pair's balances or calls sync() is effectively a price setter for that market, and it deserves the same access control as a function that mints tokens or moves treasury funds. To see how Olympix maps every path that can touch your pool's reserves and returns a runnable counterexample for any that breaks, book a technical walkthrough.

On-Chain References

Protocol: BY token and its BY/WBNB PancakeSwap V2 pair

Chain: BNB Chain

Date: June 4, 2026, 20:38:09 UTC

Loss: 146.60 WBNB net from the pair (on-chain), about $88.1K

Exploit tx: 0xe31c...0979

Block: 102329719

Attacker EOA: 0x0475...0bad

Attack contract: 0xc081...85ec

BY token (source unverified): 0x6f50...62ca

BY/WBNB pair (victim): 0x1f35...7059

Flash-loan source: 0x8f73...5d8c

See what Olympix finds on your own code

Send us a repo that's already been audited, and we'll run Olympix at the same commit and show you what comes back.