BLOCKCHAIN AI.NEWS

Security · Analysis

The Only Fix Was to Ask Everyone to Leave

Ajna V2 lost $775,400 to liquidation math. Balancer V1 lost $234,000 to a rounding error. Four days apart, on two contracts that cannot be patched — one immutable by conviction, the other by abandonment. Both teams reached for the same remedy, because it was the only one they had.

Editorial illustration: a seamless chrome monolith with no handle or keyhole beside a single open doorway spilling warm gold light
✓ Ajna incident reported by The Crypto Times (Aug 29), pool accounting credited to Defimon · Balancer V1 reported by The Crypto Times and Bitcoin.com News, analysis credited to SlowMist · Loss figures and dates cross-checked against the DefiLlama hacks database

There is a category of security incident that has no incident response. Not a slow one, not a botched one — none. The bug is real, the money is gone, the flaw is understood, and there is no sequence of actions available to anyone that closes it. Last week produced two of them in four days.

On Aug. 28, an attacker drained $775,400 from seven Ajna V2 pools on Ethereum by manipulating the protocol's liquidation accounting. On Aug. 30 or 31 — the sources disagree, and we will come back to that — another attacker took roughly $234,000 out of a Balancer V1 pool using a rounding error in six-year-old arithmetic.

The protocols could not be more different in philosophy. Ajna is immutable on purpose: no governance body, no upgrade path, no administrator key, by design and as a selling point. Balancer V1 is immutable by circumstance: shipped in 2020, superseded twice, left running because nobody turns these things off. The distinction mattered enormously to the people who built them and not at all to the outcome.

Ajna: the math worked exactly as written

Ajna's design goal was to eliminate oracles. Most lending protocols need to know what collateral is worth, which means trusting an external price feed, which is how a great many of this year's losses happened — including the $75 million Tectonic exploit four days earlier. Ajna replaced the oracle with internal auction accounting: the protocol works out prices from its own liquidation mechanics rather than asking anyone.

That removed one class of attack and created another. Per the reconstruction published by The Crypto Times, drawing on Defimon's transaction analysis, the attacker chained four operations: bucketTake to mint LP tokens to the taker, removeCollateral to pull assets out against that freshly minted LP, take() to settle the auction for a negligible quote amount, and AuctionSettle with quoteRepaid = 0 to sweep out whatever collateral remained. The chain worked under specific conditions — the Lowest Utilized Price sitting at its floor, auctions left idle — and it let collateral leave for almost nothing in return.

Analysts have not settled on which version of the attack this was. One reading, the "harvest" theory, has the attacker finding pre-existing underpriced auctions and cleaning them out. The other, the "setup" theory, has them manipulating auction pricing atomically within the same transaction. Both fit the observed traces; nobody has published a determination, and Ajna has not released a formal post-mortem or an official loss table.

Where the $775,400 went — Ajna V2, seven Ethereum pools

syrupUSDC$173.7K
wstETH$159.8K
rETH$143.0K
cbETH$136.9K
WBTC$101.8K
WETH/USDC$42.0K
sDAI$18.0K
Pool-by-pool accounting published by Defimon on Aug 29 at 09:29 UTC, as reported by The Crypto Times. The rETH and cbETH figures each combine two transactions. Bar widths are proportional to the largest pool.

The timeline is tight and well documented. Attack contracts went on-chain at 15:16 UTC on Aug. 28. The first extraction hit the cbETH pool at 16:19 UTC, in block 25854888. Ajna's public acknowledgement came at 04:58 UTC the next morning, and it was not a patch note. It was an evacuation order: withdraw all quote tokens, repay outstanding loans, and stop interacting with the protocol.

The warning that would not have helped

There is a claim attached to this incident that deserves careful handling. Defimon says it detected the prepared attack contracts more than an hour before the first extraction, notified the Ajna team through Discord, and got no response — that Ajna, in its words, failed to react.

Treat that with the skepticism it invites. Defimon is a commercial security monitoring service that sells early detection, and this is a story in which its product performs perfectly and the customer does not listen. It has not been independently confirmed, and no public statement from the Ajna team addresses it. Vendors are not obliged to be wrong, but a self-reported near-miss is marketing until someone else checks it.

What makes it worth raising anyway is that the claim, even if entirely true, does not lead where it seems to. Suppose Ajna had read the message at 15:17 UTC and believed it immediately. What then? There is no pause function. There is no admin key. There is no upgrade path. The protocol was built specifically so that nobody — including its authors — could interfere with it. The best available response to a perfect one-hour warning was to start shouting at users to withdraw, roughly an hour faster than they did.

That is the honest shape of immutability. It is usually sold as protection against the team — no rug pull, no surprise upgrade, no admin key to steal, which is a real and considerable benefit given how many of this year's losses ran straight through admin keys. What is discussed less often is that the same property removes every lever during an emergency, and the users bear that cost at exactly the moment they can least afford it.

Balancer V1: dormant, callable, and still doing its job

Balancer's V1 pools have been effectively retired for years. Development moved to V2, then V3. Nobody was maintaining the 2020 contracts. But retired, in this context, does not mean switched off — it means still holding liquidity and still answering calls from anyone who makes them.

SlowMist's analysis identifies the flaw in joinswapPoolAmountOut: the helper calcSingleInGivenPoolOut reverse-computes the required input using 18-decimal fixed-point math. WBTC has 8 decimals. Once the attacker compressed the pool's WBTC reserves to near-dust, the required input rounded down to the smallest representable unit — one satoshi — while the contract still minted the full amount of pool tokens requested. The reported result: 4,408.8 BPT for a single satoshi of WBTC, exited into DPI, USDC, WETH and WBTC, with the working capital assembled from nested flash loans across Aave, Spark, Morpho and Uniswap V3.

This is the same family of bug that hit Balancer V2 last November — a down-rounding operation that favours the caller instead of the pool. On the size of that earlier incident, the sources conflict: The Crypto Times puts it at approximately $128 million across six networks, while Bitcoin.com News reports $116 million across multiple chains. We have not reconciled them and are not going to pick one. The dates conflict too: DefiLlama's database records the V1 incident on Aug. 30, while The Crypto Times and SlowMist place it on Aug. 31.

Balancer's own answer to this bug family arrived in V3, which enforces explicit rounding direction on every arithmetic operation. That fix is real and it is shipped. It simply cannot reach backwards into V1, because V1 is not upgradeable either.

The part that has not happened yet

BPool — the V1 pool contract — was among the most widely forked pieces of DeFi infrastructure of its era. A great deal of code written between 2020 and 2022 started as a copy of it.

The exposure test, per the SlowMist-derived analysis, is narrow and mechanical: does the pool hold a token with fewer than 18 decimals, such as WBTC or USDC, and is joinswapPoolAmountOut still callable? A fork that satisfies both is vulnerable to the same manipulation. We have seen no public inventory of which forks qualify, and we are not going to estimate one — the honest statement is that nobody has published the count, and that a bug in a heavily copied contract does not stay confined to the original.

The $234,000 taken from Balancer V1 is a rounding error in more than one sense. Set against Tectonic's $75 million the same week, it barely registers. What it demonstrates is worth more than what it cost: unmaintained code with liquidity in it is not dormant. It is live software with nobody on call.

The Take

Immutability is a genuine security property and the industry is right to value it — most of 2026's worst losses went through an admin key, a governance vote, or a compromised deployer, and none of those were available here. But it is a trade, not a free upgrade, and the sales pitch consistently omits the second half: you are exchanging the risk of a malicious operator for the certainty of no operator at all. Ajna made that trade deliberately and should be judged on having made it honestly. Balancer V1 made it by default, which is worse, because nobody chose it and nobody told the depositors still sitting in those pools. If your protocol cannot be patched, the evacuation notice is your entire incident response plan — so write it before you need it, publish the conditions that would trigger it, and make sure someone is still reading the Discord six years after the last commit.

More on the subject