CryptoReal
CASE FILE — Jun 18, 2026

Dormant but Not Dead: How Aztec Connect's Abandoned Contracts Bled $2.28 Million in 48 Hours

Two attackers, working independently on two consecutive mornings, extracted a combined $2.28 million from a set of Ethereum contracts that Aztec Labs had stopped maintaining more than two years earlier. Neither the funds sitting in the contract nor the underlying source code were secret. What was missing was anyone with the authority — or the keys — to fix a flaw hiding in plain sight.

Aztec Labs deprecated Aztec Connect back in March 2023 and, in April 2024, formally gave up its administrative control over the contracts. What remained was frozen in place: immutable, unsupervised, and still custodying whatever balance its former users had never bothered to withdraw.

The attacker who struck first didn't need to break any cryptographic guarantee or steal a private key. Instead, they found daylight between two systems inside the protocol that were designed to constrain each other but, in practice, never fully did — a zero-knowledge proof validating one set of transactions, and a settlement layer executing a different one. Whatever entered the proof on one side had no bearing on what the settlement code allowed out the other.

In a single atomic transaction, the attacker pushed fourteen rollup proofs spanning seven different assets through that gap. No key compromise, no broken math — just a logic error in a contract that could no longer be paused, patched, or explained by anyone accountable for it.

The next morning, a second attacker found the identical opening, firing off another fourteen rollup calls from an unrelated wallet to mop up the leftover DeFi bridge positions the first attacker hadn't touched — roughly $88,000 more by day's end.

Three days after that, yet another attacker went after a different Aztec contract through an entirely different entry point, walking away with approximately $2.2 million more. Different incident, same underlying story: an architecture nobody was watching.

This was a protocol backed by roughly $100 million in venture funding, built on zero-knowledge research tracing back to the company's founding in 2017, and one that had previously paid out a $450,000 bounty for catching a critical bug in this same codebase back in 2023. That earlier fix was only possible because Aztec Labs still held the admin keys at the time.

By the time this new flaw surfaced, those keys had been relinquished for more than two years. When a protocol's only remaining safeguard is that nobody bothers to read its public code, that safeguard was never going to last.

Sourcing for this account draws on statements and analysis from Aztec Labs, TechCrunch, Aztec Network, the Aztec Foundation, CertiK, BlockSec Phalcon, Odysseus, Syscoin, Blockaid, SlowMist, and Defimon Alerts.

01Four Names, Four Different Things

Before going further, it's worth separating four entities that get conflated in casual retellings of this incident:

Aztec Labs — the company that built and ran Aztec Connect before giving up all administrative control in April 2024.

Aztec Connect — the legacy zk-rollup privacy product deprecated in 2023; its contracts are now immutable and were the source of the exploited funds.

The Aztec Foundationa distinct legal entity that issued a public statement on the day of the exploit, despite having no operational authority over the retired contracts.

Aztec Networkthe active product line Aztec Labs pivoted to post-deprecation, running on the Noir language and entirely untouched by this incident.

02How the Hours Unfolded

The exploit fired at 12:26 UTC on June 14. Aztec Labs says it detected the activity internally within four minutes. What followed was a slow, uneven trickle of public disclosure.

CertiK broke the news publicly 86 minutes after the funds moved, naming the attacker's address, publishing the transaction hash, and pricing the loss from the Aztec Connect Router contract at roughly $2.19 million. A follow-up post from CertiK refined the technical picture: the function computeRootHashes() only checked the front portion of the submitted _proofData, leaving the parameters that actually governed token movement buried in the middle — unchecked and effectively invisible to the proof itself.

BlockSec's Phalcon system independently flagged the same transaction, pinpointing the cause as a disconnect between the transaction set the proof validated and the boundary the L1 settlement logic actually enforced — the variable numRealTxs wasn't properly tied to what the ZK proof had verified, so the two layers ended up reading different transaction lists.

Odysseus, founder of phylax.systems, distilled both analyses into a single thread: this hit the legacy Aztec Connect rollup rather than the live Aztec Network. The attacker had bundled fourteen valid processRollup calls into RollupProcessorV3, and the on-chain trace showed genuine withdrawals — not an admin sweep, not a token-approval drain.

Aztec Labs itself stayed quiet for 74 minutes after CertiK's initial post. When the company finally spoke, the statement ran four sentences: "We are investigating a potential exploit affecting Aztec Connect. ~$2.1m was transferred from the immutable smart contract in a transaction. Aztec Connect was deprecated 3 years ago. Aztec Labs holds no admin keys or control over the system; it cannot be paused or upgraded by us. We will share further updates in due course."

Two minutes later, the Aztec Foundation added one useful clarification: the deprecated contracts had no connection to the AZTEC ERC-20 token or to the current Aztec Network. Between the two statements, there was still no technical detail, no timeline, and no commitment to a follow-up report — information that would only surface later.

For comparison, Syscoin, which had suffered its own bridge exploit exactly a week earlier, had already published a detailed preliminary post-mortem before most of its community was even awake, naming the flaw, listing every transaction hash, flagging tainted wallets, and confirming a fix. Aztec Labs had no fix to offer and no recoverable funds — but it did have information, and for the first several hours it held onto that information rather than sharing it. Absent admin keys, transparency was the only tool left, and it went largely unused early on.

When Aztec Labs eventually published its full technical write-up, it was thorough — but by then, outside researchers had already filled most of the informational vacuum.

Blockaid had actually caught the attacker's contract deployment before the drain occurred, roughly six minutes ahead of the $2.19 million exiting the contract — a detection Aztec Labs later credited explicitly, though the six-minute window wasn't enough to stop anything.

Defimon Alerts produced the most granular early breakdown of the stolen assets: 909 ETH, 270,513 DAI, 167.89 wstETH, alongside LUSD, yvDAI, yvWETH, and yvLUSD. The attacker's wallet was brand new, with only nine prior transactions, and the sheer variety of assets moved was inconsistent with a legitimate user simply withdrawing their own position.

SlowMist published a full independent forensic write-up the following day, reconstructed entirely from open-source contract code and raw calldata, and gave the vulnerability a name none of the earlier alerts had used: a settlement boundary bypass.

While that first wave of reporting was still unfolding, a second exploit was already underway. At 20:28 UTC on June 14 — eight hours after the initial drain — a new wallet was funded through a relayer contract. By 04:00 UTC on June 15, that wallet had begun submitting fourteen more rollup calls, continuing exactly where the first attacker had left off and targeting the residual DeFi bridge positions the earlier drain hadn't collected. Roughly $88,000 more disappeared before the day ended — same bug, same contract, a different wallet walking through a door someone else had left open.

One additional detail surfaced quietly around the same time: on March 17, 2026, Aztec Labs' own engineers had discovered an unrelated critical vulnerability in the live Aztec Network's Alpha v4, with a fix scheduled for the v5 release in July. Details of that bug and its patch are being withheld until v5 ships.

So the picture by mid-June was this: a deprecated contract drained across two consecutive mornings for $2.28 million combined, and a live, actively used network quietly sitting on an unpatched critical bug. The team that wrote the code, operated the sequencer, and set the terms of the shutdown had, when the moment came, nothing left to offer but a press statement.

03Where the Proof and the Settlement Layer Disagreed

Sums referenced in this case file

Every Aztec Connect rollup bundled individual transactions into what the protocol internally called "rows." Two separate subsystems processed each batch of rows, and neither one was bound to respect the other's boundaries.

The first subsystem was the zero-knowledge validity proof. Its job was to guarantee that balances reconciled, that no value appeared from nowhere, and that the new state followed logically from the old. For efficiency, it processed rows in fixed groups of 32 — even when a batch used only a few of those slots, the proof still committed to the entire group of 32.

The second subsystem was the Ethereum settlement contract itself, and it worked differently: rather than re-checking every row, it trusted a single value embedded in each batch, numRealTxs, which declared how many of the rows were "real," and it only acted on that many. The proof committed to a full 32-row chunk; the settlement loop stopped wherever numRealTxs said to stop. Same calldata, two different boundaries. The L1 contract assumed the proof made everything past numRealTxs harmless — but the proof never actually enforced that.

That mismatch was the entire exploit. The attacker set numRealTxs = 1 on each of the fourteen calls to processRollup(), while quietly packing two state-changing rows into the calldata for each call. Both rows fell inside the same 32-slot chunk the proof committed to — but the settlement loop, bound by numRealTxs, processed only row 0. Row 1 was accepted by the proof and folded into the rollup's internal state, yet it never reached the L1's deposit-accounting logic at all.

Row 1 is where the fake deposit lived — sized precisely to match the withdrawal that would follow. Because it sat past the numRealTxs cutoff, processDepositsAndWithdrawals() never executed for it, which meant decreasePendingDepositBalance() was never triggered either — no actual funds were ever pulled in. Yet the proof had already certified that deposit as legitimate, so the rollup's internal ledger updated as though the money had genuinely arrived. The attacker now held a credited balance the contract believed was real.

The withdrawal followed, placed at row 0 — squarely inside the enforced boundary, and fully executed by the L1 settlement code. Real assets moved to the attacker's wallet.

Across all fourteen rollup calls, the pattern repeated identically: the first seven calls placed a harmless transaction at row 0 while quietly accumulating a fake deposit at row 1; the remaining seven calls cashed out that fabricated balance, one genuine withdrawal per call, one asset at a time.

Aztec Labs' own post-incident report described the flaw directly: "It is possible to submit a row that is accepted by the proof, but that the settlement code never processes. These checks would ensure, for example, that a deposit into an account was based on real funds sent to the rollup. So internal balances of users can be updated without legitimate deposits."

Aztec Connect's deposit flow was designed as a two-step process: first, depositPendingFunds() pulls actual ETH or ERC-20 tokens into the RollupProcessor and increases a pending-deposit counter. Second, a counted deposit row consumes that pending balance — at which point the L1 checks authorization and decrements the pending figure. Because the attacker's deposit rows sat at row 1, outside the enforced boundary, that second step simply never ran. The pending balance was never reduced, no real funds ever backed the credited amount, and the ZK proof had already marked the resulting state as valid.

Worth noting: the root issue wasn't a missing access-control check. The fact that processRollup() remained publicly callable after Aztec Connect's sunset was a contributing condition, not the actual vulnerability. The boundary mismatch on numRealTxs is what emptied the contract, as BlockSec's analysis concluded, and SlowMist's independent write-up landed on the same label: a settlement boundary bypass.

The cryptography itself never failed — the ZK proof performed exactly the function it was designed for. The failure was architectural: the settlement contract trusted the proof to enforce a rule the proof was never built to enforce. Had either side closed that gap — the L1 rejecting state-changing rows beyond numRealTxs, or the circuit treating those rows as inert padding — the exploit wouldn't have worked. Neither side did. Each assumed the other was covering it.

It remains an open question whether this flaw had existed from the start or was introduced with the contract upgrade on April 10, 2024, which reportedly went live without an external audit.

04The Numbers

Attack one was fast and self-contained. At 12:26 UTC on June 14, a single atomic transaction ran through a primary helper contract and issued fourteen calls into the Aztec Connect proxy. Seven of those calls were withdrawals, each pulling a distinct asset — ETH, DAI, wstETH, yvDAI, yvWETH, LUSD, and yvLUSD — clear of the contract in under sixty seconds, all landing at the attacker's externally owned account.

The attacker's wallet had been funded through Tornado Cash at 09:26 UTC that same day, roughly three hours ahead of the exploit itself.

Between 12:16 and 12:26 UTC, the attacker deployed five contracts inside a ten-minute window — preparation that was clearly deliberate, executed on a tight schedule.

The full haul: 908.99 ETH, 270,513 DAI, 167.89 wstETH, 4,873.86 yvDAI, 16.57 yvWETH, 9,273.73 LUSD, and 359.05 yvLUSD — approximately $2.19 million at the time of the exploit. There were no same-block offsetting flows and no round-trip movement: the proxy paid the attacker directly, and the intermediate helper contracts held nothing once the transaction finished. As of June 15 — a full day later — SlowMist confirmed that 100% of the funds from this first attack remained untouched in the same attacker EOA, with nothing moved or laundered.

Attack two began eight hours after the first, when the same door was found open again. At 20:28 UTC on June 14, a second, unrelated wallet received 0.1 ETH through a relayer contract. Nothing confirms this was the same attacker — different wallet, different funding source, different setup — but it exploited the identical vulnerability, the identical contract, and the identical method, arriving almost like a second scavenger following the first.

By 04:00 UTC on June 15, this wallet was submitting rollups, starting at rollup ID 13,291 — precisely where the first attacker's sequence had ended at 13,290. Fourteen more calls ran through 05:17 UTC, this time targeting the residual DeFi bridge positions that had built up inside the rollup contract over Aztec Connect's active years.

Extracting this second batch was more involved, since these weren't straightforward deposits but wrapped yield-bearing tokens from Aave, Compound, and TroveBridge. wa2WETH, wa2DAI, and wcDAI were pulled out through the same boundary bypass and then unwound outside the protocol: wa2WETH converted to WETH and then to ETH, while wa2DAI and wcDAI both converted to DAI. The TroveBridge position needed one additional step — the attacker sent the TB-275 token back into the rollup contract itself, which converted it to ETH and released it. A separate Euler-wrapped WETH position, weWETH, was pulled out but had no redeemable underlying WETH backing it at the time.

Assets taken in the second attack: 36.39 wa2WETH, 6,706.26 TB-275, 3,220.84 wa2DAI, 622.74 wcDAI, and 42.82 weWETH — roughly $88,000 total.

Aztec Labs listed the intermediary wallets only in truncated form in its report; the full, on-chain-verified addresses are:

Aztec Labs' incident report described the final destination only as a high-volume service contract with roughly 1,900 depositors; tracing the actual contract address confirms it was Tornado Cash.

Combined, the two attacks totaled approximately $2.28 million. The first attacker claimed the principal — unclaimed user deposits that had sat untouched since deprecation. The second cleaned up the remainder — three years' worth of unwound DeFi bridge positions. Between the two, everything the vulnerability made reachable was gone. The first attacker's funds have not moved since; the second attacker's funds are already gone.

05The Aftermath

This exploit left the current Aztec Network completely unaffected. Its impact on the AZTEC token was minimal — the token was actually up slightly that day, suggesting the market correctly priced the ring-fencing between the deprecated contracts and the live network. Current network users were never exposed.

The people who did bear the loss were those whose funds had sat inside the retired contract — users who hadn't withdrawn during the year Aztec Labs urged them to, who lost access to the escape hatch once Aztec Labs stopped running the sequencer, or who may not have even realized their assets were still there. None of them have any recourse — no compensation plan, no recovery path.

To be fair, Aztec Labs gave users more than a year of advance notice, published reminders, and built out exit infrastructure — the standard playbook for winding down a protocol responsibly. And yet millions of dollars were still sitting in the contract when the first attacker arrived.

Aztec Connect occupies an unusual place among 2026's exploits: it wasn't a live protocol, an active bridge, or a team still running operations. It was a fully wound-down, fully immutable system that still ended up fully drained — proof, in the starkest terms, that deprecation is not deactivation and immutability is not safety. Any open-source contract still holding real value functions as a standing, unexpiring invitation to whoever is patient enough to find its gaps.

Three days after the first two attacks, a third contract and a different entry point proved the point again — Aztec's retired infrastructure was still being read closely by outsiders. This time the exploit ran through the Escape Hatch circuit, letting invalid proofs pass on-chain and draining approximately $2.2 million more. The underlying gap — contracts still live, still readable, still unmonitored — was never actually closed.

A separate, upcoming piece will cover the June 17 Private Rollup Bridge exploit in full: the Escape Hatch vulnerability, the attacker behind it, and how the drain unfolded.

Taken together, the totals are stark: $2.28 million lost, against zero active audits, zero bug bounty coverage, zero monitoring, and zero ability for anyone to respond even if they wanted to. That's not a security model — it's a contract running on borrowed time, holding other people's money in public, with its source code open to anyone with a browser and the patience to read it. The users affected did nothing wrong; they had used a protocol that had once been audited, actively maintained, and backed by serious capital. The shutdown itself was handled by the book. The outcome was identical to a rug pull anyway.

Aztec ConnectAztec Labs
Investigation alerts

Get new scam files the moment we publish them — usually 2–3 emails a week.

Enter a valid email address.

No spam, unsubscribe anytime. We never sell your data. Crypto assets are volatile and high-risk; nothing here is financial advice.

You're on the list. Watch your inbox for the next scam file.