October 20, 2026
|
Exploit Postmortem
Cover image for "CashCowCoin's $117K Loss and How Olympix Would Have Prevented It"

CashCowCoin's $117K Loss and How Olympix Would Have Prevented It

Date: August 27, 2026

Chain: BNB Chain

Loss: 165.47 WBNB, about $117K

Class: a public sell path that burned tokens out of its own liquidity pool and re-synced the pool's reserves

CashCowCoin went live on BNB Chain on August 26, 2026, with a launch post built around removing its own ability to do harm. The team said it had burned liquidity permissions covering 80% of the 210 million CCC supply to a dead address, shipped a token with no mint function at all, and put rule changes behind DAO votes and a timelock.

The next day, one transaction took 165.47 WBNB, about $117,000, out of CCC's own PancakeSwap pool. The attacker bought CCC once and then sold it back 80 times through the project's public sell function, and every one of those sells burned CCC straight out of the pool and then told the pool to update its books. The safeguards the team had built limited what the team could do to supply, and none of them covered what an outside caller could do to the pool through sell().

A Sell Function That Also Burned

CCC trades through an upgradeable trading proxy, an EIP-1967 contract at 0xf523...41c7 whose buy() and sell(uint256,uint256,uint256) functions are public, so any holder can trade through it. According to the DeFiHackLabs proof of concept, each call to sell does three things. It swaps CCC for WBNB through the real CCC/WBNB PancakeSwap V2 pair, then calls a privileged function on the CCC token, selector 0xb20a0b6f, which the PoC labels TreasuryRefilled, to burn the freshly received, post-tax CCC straight out of the pair to the dead address, and finally calls pair.sync().

A PancakeSwap pair prices every trade from its two recorded reserves, and sync() overwrites those reserves with whatever balances the pair actually holds. So after each sell, the pair's CCC reserve was reset to a figure smaller than the trade had left it, while its WBNB reserve stayed where the swap put it.

The burn function had a gate, and only the proxy could call it directly, so a bare call from any other address reverted. That gate didn't help, because the proxy's own public sell path called burn on every seller's behalf.

How a Shrinking Reserve Pays Out

A constant-product pool keeps its price honest by making each trade move the reserves in opposite directions: sell CCC into the pool and its CCC reserve grows while its WBNB reserve shrinks. CashCowCoin's sell path undid the first half of that on every call. The CCC that a seller had just added was burned out of the pool and the reserves were re-synced, so the pool behaved as if the CCC had never arrived, while the WBNB it had paid out was gone for good.

A pool's reserves are only meaningful if the only way to change them is a trade the pool priced itself. Picture a currency exchange booth where, after every customer sells dollars, a manager quietly takes those dollars out of the drawer and re-counts the till. The booth still thinks dollars are scarce and keeps paying out at the old rate, and a customer who sells the same dollars over and over can empty the other side of the drawer.

Eighty Sells in One Transaction

The attack ran in transaction 0x89d8...ad43 in block 118384061, sent from the wallet 0x7977...13C4 through a helper contract. No PancakeSwap V2 pool held enough WBNB to flash-swap from, so the attacker took a flash loan of 416,831 WBNB from Moolah, a lender that let the money be borrowed and repaid within the same transaction.

The first move was a donation. The attacker sent 13,999.89 WBNB straight into the CCC/WBNB pair and called sync(), which the DeFiHackLabs author describes as working float that let the drain finish in 80 steps. Next came a single buy() through the proxy with 402,831.6 BNB, which returned 8,805,839.8 CCC after the token's transfer tax.

Then came 80 sells, each one an eightieth of that CCC. Every sell swapped CCC into the pair for WBNB, burned about 104,569 CCC back out of the pair, and called sync(). The pair's CCC reserve stayed at roughly 326,767 the whole way through, while its WBNB reserve stepped down with every cycle.

After the last sell, the attacker wrapped the BNB proceeds, repaid the Moolah loan and kept 165.471928251512413319 WBNB, which the PoC identifies as the entire WBNB side of the pair. That figure lines up with the roughly $117K that TenArmorAlert reported.

After the Alerts

DefimonAlerts and TenArmorAlert flagged the incident on August 28, and TenArmorAlert traced it to the token's sell() function, which it said was used to burn CCC directly from the liquidity pair before the price moved abnormally. Crypto.news reported no response from the team on pausing the contract, recovering funds or compensating liquidity providers, and no later statement has appeared in the sources found.

How Olympix Catches a Sell Path That Rewrites Its Own Reserves

Olympix reads a contract the way an attacker does, as states, transitions and entry points. For CashCowCoin, the state that matters is the CCC/WBNB pair's recorded reserves, since every price the pool quotes comes from them, and every public entry point that can move those reserves is a path worth mapping. The engine also takes in the context around the code, here that the token's sell function sits on top of a live AMM pair, to infer the invariants the system relies on without ever stating them.

Olympix's static analysis surfaces the signal: a public, permissionless function whose output depends on the pair's spot reserves, and which in the same call burns tokens out of that pair and calls sync(), letting any caller rewrite the reserves the next trade will be priced from. Olympix has flagged this class of spot-reserve price manipulation before in other codebases. The signal narrows the search from every path in the proxy to the feasible ones a holder can reach, and from there to the ones that touch the pair's reserves.

BugPoCer works on the pool's side of the story. It runs Counterexample-Guided Invariant Refutation, starting from the proxy, the token and the pair as one system, and infers the rule the pair depends on: a seller can only receive the WBNB that honest liquidity supports for the CCC they actually added, so repeating a sell can never pay out more than the pool's real depth allows. From there it executes paths through buy() and sell() until a sequence of them breaks that rule.

The counterexample comes back as the August 27 attack: borrow WBNB, buy CCC once, call sell() repeatedly while each call burns from the pair and re-syncs, and watch the WBNB reserve fall faster than any honest sequence of trades could move it. BugPoCer returns that sequence with the minimal conditions that trigger it and a generated Forge test that replays it, produced in development instead of on mainnet. Because the engine runs automatically during development, at every merge and before release, a deflationary burn step added to a sell path gets tested against the pool it touches the day it's written.

Burns Belong Outside the Pool's Books

CashCowCoin did the hard work of removing its own ability to mint or pull liquidity, and the loss came from a different place, a public sell path allowed to edit the reserves its own price came from. Any token that burns, taxes or rebalances inside an AMM pair needs the same scrutiny as its admin controls, because those mechanics change the pool's books for every trader who comes next. If you're shipping custom token mechanics on top of a live pool and want to see the counterexamples Olympix produces against them, book a technical walkthrough.

On-Chain References

Protocol: CashCowCoin (CCC) trading proxy and CCC/WBNB PancakeSwap V2 pair

Chain: BNB Chain

Date: August 27, 2026, 12:31:31 UTC

Loss: 165.471928251512413319 WBNB (about $117K)

Flash loan: Moolah, 416,831 WBNB

Attacker EOA: 0x7977...13C4

Attack contract: 0x7738...EaAf

CCC trading proxy (vulnerable contract): 0xf523...41c7

Trading proxy implementation: 0x4287...A9ac

CCC token: 0xb9B8...3CCC

CCC/WBNB PancakeSwap V2 pair: 0x1DBE...97c0

Moolah lending pool (flash loan): 0x8F73...5D8C

Exploit tx: 0x89d8...ad43

Block: 118384061

Sources

DeFiHackLabs PR #1277: CashCowCoin PoC

DeFiHackLabs: CashCowCoin_exp.sol

Crypto.news: CCC exploit drains $117K after attacker targets BSC liquidity pool

DefimonAlerts: CashCowCoin exploit alert

ME on Paragraph: CashCow Goes Live

More from Olympix:

No items found.

Ready to Shift Security Assurance In-House? Talk to Our Security Experts Today.