On 14 June 2026, at 12:26 UTC, an attacker drained approximately $2.19M of assets from the Aztec Connect rollup contracts on Ethereum in a single transaction (0x074ec931…aeeb1).
On 15 June 2026, beginning at 04:00 UTC, a second exploit targeted the same Aztec Connect vulnerability to extract approximately $88k of residual value from the leftover DeFi bridge positions, across 14 transactions (rollupId 13291–13304).
Important to note
- Aztec Connect was deprecated in 2023. In April 2024, we revoked all administrative roles and renounced all upgrade authority onchain after a year of notice to users. Aztec Labs holds no control over these contracts.
- The proof system (including the trusted setup) was not compromised in the incident.
- The exploit targeted an issue in the Solidity smart contracts where the side-effects of a given rollup proof were not asserted to be the same as the ones processed by the deposit-withdrawal system. We are appreciative of Blockaid, who independently flagged a pre-transaction setup step and helped accelerate identification of the incident.
- The bug was not discovered under an external audit.
- Aztec Connect was under an active bug bounty from launch through until 2024, when Aztec Labs deliberately renounced all control of the rollup.
- This does not affect any active products and only relates to the deprecated Aztec Connect system. The live Aztec Network and present-day systems are entirely separate and are not impacted.
Incident timeline (UTC)
| When (UTC) | Event |
|---|---|
| 14 Jun 09:26 | First attack begins. Attacker funds a fresh wallet (0x0F18…EdD17) via Tornado Cash. |
| 14 Jun 12:16 | Attacker deploys a set of helper contracts. |
| 14 Jun 12:26 | Single exploit transaction: the attacker submits 14 crafted rollups (rollupId 13277–13290) and drains ~$2.19M to their wallet (a pre-transaction setup step was independently flagged by Blockaid). |
| 14 Jun 12:30 | Incident identified; investigation and this disclosure followed. |
| 14 Jun 20:28 | Second attack begins. A second, fresh wallet (0x7ec9…06db) is funded with 0.1 ETH via a relayer contract. |
| 15 Jun 04:00 | First of 14 rollup submissions (rollupId 13291), continuing the chain from exactly where the first incident stopped. |
| 15 Jun 04:00–05:17 | 14 separate processRollup calls (rollupId 13291–13304), interleaved with a series of DeFi bridge unwinding operations. |
| 15 Jun 06:40 | The extracted ETH is funnelled through intermediary wallets toward a high-volume exchange-like service. |
What is Aztec Connect?
Aztec Connect is a privacy-preserving zk-rollup on Ethereum, launched in 2022 and deprecated in 2023. It let users shield assets and interact privately with DeFi protocols (Lido, Yearn, and others) through a rollup that batched many user transactions into a single Ethereum settlement, with correctness guaranteed by a zero-knowledge validity proof.
In April 2024, after one year of supported exits and reminders urging all users to withdraw their funds, we formally and permanently relinquished control of the contracts onchain, in order to ensure users could continue to exit with no input from Aztec Labs.
Technical details of the exploit
Background
Every Aztec Connect rollup bundles a batch of individual transactions; we will call each one a “row.” Two separate parts of the system act on that batch, and the vulnerability stemmed from disagreements amongst those two sub-systems.
- The validity proof is what guarantees the batch is internally consistent: that balances add up, nothing is created from nothing, and the new state follows correctly from the old. For efficiency, the proof examines rows in fixed-size groups of 32. Even when only a few rows in a group are used, the proof still checks and accepts the whole group of 32.
- The onchain settlement code (the Ethereum contract) does not re-examine every row. Instead it trusts a single number carried in the batch,
numRealTxs, which declares how many rows are “real,” and acts on only that many.
The problem is in how these two systems interact. The proof accepts a whole group of 32 rows, but the settlement code only acts on the first numRealTxs of them. As a result, 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.
The exploit
The first attack drained the contract in a single transaction. Through a set of helper contracts, the attacker made 14 calls to the rollup contract's settlement function, processRollup. Each call carried a valid proof, and was crafted the same way:
| Data | Value |
|---|---|
numRealTxs — how many rows the settlement code will act on |
1 (row 0) |
| Rows actually packed into the batch | 2 (row 0 and row 1) |
| Rows the validity proof checks and accepts | all rows |
| Rows the settlement code processes for real assets | row 0 only |
In every call, row 1 was accepted by the proof, but never settled onchain. The 14 calls then played two roles. Some used row 1 to create balance, the rest used row 0 to take it out. The process was similar for all assets:
- Mint balance without paying for it. In each rollup, row 0 was a harmless internal transfer, which the settlement code processed normally. Row 1 was a deposit for a large amount: the proof accepted it and credited that balance inside the system, but because row 1 sat past
numRealTxs, the settlement code never actually collected the deposited funds. The attacker now held internal balance backed by no real assets. - Withdraw assets. In later rollups, the attacker placed an ordinary withdrawal at row 0 and the contract paid it out in ETH or tokens to their wallet. Repeated across 14 batches in a single transaction, this drained the assets.
The second attack exploited DeFi bridge positions held by the rollup contract. The attacker used the same principle to move weWETH, wa2WETH, wa2DAI, wcDAI, and initially TB-275 to their wallet. The attacker then redeemed the Aave and Compound wrapper tokens directly from their own wallet, outside Aztec Connect: wa2WETH became WETH and then ETH, while wa2DAI and wcDAI became DAI. To unwind TroveBridge value, the attacker sent the TB-275 position token back to the rollup, causing the rollup to convert it to ETH and then send it back to the attacker.
The extracted ETH and DAI were funnelled through a short chain of disposable wallets (0x7ec9…06db → 0xc431…c1f5 → 0x0af7…9912 → a high-volume service contract at 0xd90e…f31b, which has received deposits from roughly 1,900 distinct addresses). That pattern is consistent with depositing into a centralised exchange or a swap service. The residual Euler-wrapped WETH remains in the attacker's wallet, but it had no redeemable underlying WETH at the time checked.
Extracted assets: first attack
| Asset | Amount |
|---|---|
| ETH | 908.986707307963496632 |
| DAI | 270,513.054157632152892774 |
| wstETH | 167.890392526462638142 |
| yvDAI | 4,873.856656463299373447 |
| yvWETH | 16.569551230652464753 |
| LUSD | 9,273.734320992446140764 |
| yvLUSD | 359.047484523695640986 |
| Total | ~$2.19M at time of exploit |
Extracted assets: second attack
| Asset | Amount |
|---|---|
| wa2WETH | 36.386261815396708763 |
| TB-275 | 6,706.255705482134564188 |
| wa2DAI | 3,220.837902125260802329 |
| wcDAI | 622.738923695803816639 |
| weWETH | 42.824580045075249388 |
| Total | ~$88k (weWETH had no redeemable underlying at time of exploit) |
Core impacts
- The primary attack drained assets (ETH, DAI, wstETH, several Yearn vault tokens, LUSD) valued at approximately $2.2M at the time of the exploit.
- The secondary attack extracted approximately $88k of residual value from leftover DeFi bridge positions.