On 17 June 2026, at 18:34 UTC, an attacker drained approximately $2.2M of assets from the original Aztec 2.0 rollup contract on Ethereum, across three transactions. Aztec 2.0 was Aztec's original privacy-preserving zk-rollup on Ethereum, launched in 2021 and deprecated in 2022.
The exploit targeted an unsound verification key behind the contract's escape-hatch verifier. Specifically, the deployed escape-hatch circuit accepted a withdrawal that was not backed by any real deposit.
On 18 June 2026, at ~08:16 UTC, a second, seemingly unrelated actor reproduced the same technique to sweep the leftover 0.76 ETH (rollupId 4490). The contract is now empty.
This incident follows a 15 June 2026 incident draining a different deprecated rollup, Aztec Connect.
Important to note
- This does not affect any active products and only relates to the deprecated Aztec 2.0 rollup. The live Aztec Network and present-day proof systems are entirely separate and are not impacted.
- Aztec 2.0 was deprecated in 2022, superseded by Aztec Connect (which was later deprecated in 2023). It has not been a maintained or active product since.
- Aztec Labs holds no control over this contract. In April 2024, we revoked all administrative roles and renounced all upgrade authority onchain (tx
0x72c4…8194) after a year of notice to users. - The shared cryptographic trusted setup was not compromised. The verifier itself worked as intended, but the flaw was in the circuit logic behind the verifier key.
Incident timeline (UTC)
| When (UTC) | Event |
|---|---|
| 17 Jun 18:21 | Attacker funds a fresh wallet (0x6952…E97F) with 0.13 ETH for gas. |
| 17 Jun 18:34 | Withdrawal #1: the escape hatch is used to drain 1,158 ETH (0xab30…2b5). |
| 17 Jun 18:49 | Withdrawal #2: 150,000 DAI drained (0x5c19…05c3). |
| 17 Jun 18:50 | Withdrawal #3: 0.47 renBTC, the entire balance, drained (0x9e1d…03ca). |
| 18 Jun ~08:16 | A separate copycat actor sweeps the residual 0.76 ETH via the operator path (0x389b…cb0c). The contract is now empty. |
The attacker's main attack, from gas funding to the final asset drain, took roughly 37 minutes.
What is Aztec 2.0?
Aztec 2.0 was Aztec's original privacy-preserving zk-rollup on Ethereum, launched in 2021 and deprecated in 2022. Aztec 2.0 let users shield assets and transact privately, batching many user transactions into a single Ethereum settlement with correctness guaranteed by a zero-knowledge validity proof. It was an early, pioneering design, later superseded by the Aztec Connect system in 2022.
In April 2024, after a year of supported exits and reminders urging users to withdraw their funds, we formally and permanently relinquished control of the contract onchain. This allowed users to continue to exit with no input from Aztec Labs by running their own infrastructure.
Technical details of the exploit
Background
To withdraw funds from Aztec 2.0, a user must submit a cryptographic proof that they own the funds, that the funds were genuinely deposited, and that those funds have not already been spent. Two parts of the system work together:
- The verifier is the onchain machine that checks each proof against a set of baked-in rules using a verification key. This is what guarantees a proof is honest.
- The settlement contract does no reasoning of its own about who owns what. By design, it relies on the verifier to enforce ownership rules.
The contract also included an escape hatch, a public function allowing users to withdraw their own funds directly in the event the operator ceased to function. The security of this escape hatch was guaranteed by a proof system: each escape-hatch proof is checked against a set of constraints a valid proof must satisfy.
Details of exploit
From our analysis, the root cause is a soundness bug in the escape hatch circuit that allowed the attacker to withdraw funds that were never deposited or owned by them.
The exact mechanism is not provable from onchain data alone. However, our leading hypothesis involves a flawed decoupling of two values that should have been forced to match. Ownership of funds is proven against the contract's ledger, which is summarised by a cryptographic fingerprint (a Merkle root). The escape-hatch code uses this fingerprint twice, and never checks that the two uses agree.
| Value | What it is used for | What the attacker set it to |
|---|---|---|
| Membership root | The ledger the proof checks fund ownership against | A fake ledger the attacker invented, in which they hold the target funds |
| Settlement root | The ledger the contract validates against the live chain | The genuine, live onchain root |
Because the contract never required these two values to be equal, an attacker could prove ownership against a fabricated ledger while presenting the genuine ledger on L1. Both checks passed independently, and the contract had no means of detecting the discrepancy.
We confirmed the failure directly onchain. The attacker's proof explicitly states deposit = 0, withdraw = 1,158 ETH, and the notes it cites as the source of those funds are fabricated, which cannot occur in a legitimate proof. The verifier accepted it and the contract paid out. Notably, the verifier was neither broken nor empty: re-running it confirms that tampering with the proof in other ways causes it to reject. The fact that this forged proof nonetheless passed is the contradiction that identifies the flaw as residing in the verification key.
Assuming that was the mechanism, the attack proceeded as follows:
- Funded a fresh wallet with 0.13 ETH for gas.
- Read the contract's live state from the public chain and copied its genuine Merkle roots into the proof, ensuring the contract's own bookkeeping checks passed.
- Constructed a forged proof for "withdraw 1,158 ETH to me", backed by fabricated notes verified against a self-generated ledger.
- Submitted it through the public escape hatch. The verifier accepted it and the contract released 1,158 ETH.
- Repeated the process for the remaining two assets, one per transaction.
The second attack applied the same principle to extract the residual 0.76 ETH approximately 14 hours later. It used the normal operator path rather than the escape hatch, which was possible because a default Anvil/Hardhat developer test account had been registered as an authorised operator as part of the 2024 decommissioning.
Extracted assets: first attack
| Asset | Amount | Approx. value |
|---|---|---|
| ETH | 1,158.0 | ~$2.04M |
| DAI | 150,000.0 | ~$150,000 |
| renBTC | 0.46963295 | ~$7,000 (upper bound) |
| Total | ~$2.2M at time of exploit (renBTC is a deprecated, depegged asset; its real value is likely far lower) |
Extracted assets: second attack
| Asset | Amount | Approx. value |
|---|---|---|
| ETH | 0.759804206229645062 | ~$1,300 |
Core impacts
- The primary attack drained ETH, DAI, and renBTC valued at approximately $2.2M at the time of the incident, the overwhelming majority of it in ETH.
- The secondary attack extracted the residual approximately $1,300 in ETH.
- The contract is now empty: zero ETH, zero renBTC, and a few dollars of DAI dust.
- We are working with our incident response provider, Groom Lake, to block funds across exchanges.