Aztec Connect $2.2M Exploit: How a Trust Boundary Flaw in ZK Rollup Led to Fund Loss
Published by onchain-shadow | June 2026
TL;DR
On June 14–18, 2026, an attacker drained approximately $2.2 million from Aztec Connect's deprecated RollupProcessorV3 contract on Ethereum. The exploit targeted a subtle but critical trust boundary mismatch between the zero-knowledge proof verification path and the Layer-1 settlement logic in the processRollup() function — specifically through the Escape Hatch mechanism. By manipulating the numRealTxs parameter, the attacker created unbacked L2 balances and then withdrew real assets from the L1 liquidity pool. This article provides a comprehensive technical analysis of the exploit mechanics, on-chain fund tracing, root cause dissection, and defensive recommendations for ZK rollup developers and the broader Web3 security community.
1. Incident Overview
1.1 What Happened
Aztec Connect was a privacy-focused zk-rollup bridge launched in 2022 by Aztec Labs. It allowed users to interact with Ethereum DeFi protocols like Aave and Lido while shielding transaction details through zero-knowledge proofs. The system was built on the principle that privacy and composability could coexist within a rollup framework.
However, by early 2023, Aztec Labs had shifted strategic focus toward building the next-generation Aztec Network — a full privacy-focused L2 with private smart contracts. Aztec Connect was officially deprecated in March 2023. Users were given over a year to withdraw their funds. The sequencer stopped running by March 2024.
By 2024, all administrative controls had been relinquished. The smart contracts became fully immutable and unpausable — a deliberate design choice consistent with the protocol's privacy-first philosophy. No single entity could modify, pause, or upgrade the contracts. The code would live on Ethereum forever, exactly as deployed.
Despite the deprecation and the team's repeated advice for users to withdraw, approximately $2.15 million in crypto assets remained custodied within the RollupProcessorV3 contract. These funds were essentially orphaned — sitting in an abandoned, immutable contract with no one able to intervene if something went wrong.
On June 14, 2026, at approximately 12:26 UTC (block 25,315,715), something did go wrong.
An attacker operating from the externally owned address 0x0f18…edd17 — which had been previously funded via Tornado Cash, indicating premeditation — executed a sophisticated exploit that drained nearly all remaining funds from the contract in a single atomic transaction. The attacker submitted 14 consecutive processRollup() calls using batched rollup IDs from 13277 to 13290, extracting funds across 7 different asset types.
Security firm CertiK flagged the suspicious transaction at approximately 13:52 UTC, roughly 86 minutes after the initial exploit. BlockSec Phalcon published a detailed technical analysis shortly after, and SlowMist released a comprehensive report identifying the root cause.
1.2 Stolen Assets Breakdown
| Asset | Amount | Approximate Value |
|---|---|---|
| ETH | 908.99 | ~$1.565M |
| DAI | 270,513 | ~$270K |
| wstETH | 167.89 | ~$357K |
| yvDAI | Small amount | Included in total |
| yvWETH | Small amount | Included in total |
| LUSD | Small amount | Included in total |
| yvLUSD | Small amount | Included in total |
| Total | ~$2.19M |
1.3 Aztec Labs' Response
Aztec Labs confirmed the incident on X (formerly Twitter) within hours:
"We are investigating a potential exploit affecting Aztec Connect. ~$2.1m was transferred from the immutable smart contract. 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."
The Aztec Foundation issued a separate statement emphasizing that the exploit had zero impact on the current Aztec Network, its active smart contracts, or the AZTEC ERC-20 token. The two systems were architecturally separate, and the vulnerability was confined to the legacy RollupProcessorV3 contract.
Users were reminded that they had been advised multiple times in the past to withdraw funds from the legacy system. The current Aztec Network continued operating independently, with a planned fix for a separate (unrelated) critical bug in its Alpha v4 proving system scheduled for July 2026.
1.4 Market Impact
Interestingly, the exploit had minimal impact on the AZTEC token price. As of June 15, 2026, AZTEC was trading at approximately $0.01586, with a 24-hour price increase of around 5.1–5.3%. The token's market capitalization stood at approximately $46.56 million, with a circulating supply of 2.941 billion AZTEC. The market appeared to price in the fact that this was a legacy system issue, not a fundamental threat to the current network.
2. The Escape Hatch Mechanism: Technical Deep Dive
2.1 What Is the Escape Hatch?
The Escape Hatch (also known as "exit hatch" or "emergency exit") is a standard safety mechanism in ZK rollup designs. Its purpose is to provide users with a guaranteed path to exit the system and recover their assets even when the L2 sequencer is unavailable, censored, or permanently offline.
In a normal ZK rollup operation:
- Users submit transactions to the L2 sequencer
- The sequencer batches transactions and generates a ZK proof
- The proof is submitted to the L1 contract (RollupProcessor)
- The L1 contract verifies the proof and updates the rollup state
- Users can withdraw their assets based on the verified L2 state
The Escape Hatch provides an alternative path when step 1–2 cannot happen (because the sequencer is down):
- A user independently generates an "escape hatch proof" — a ZK proof demonstrating their legitimate balance on L2
- The user submits this proof directly to the RollupProcessorV3 contract on L1
- The contract verifies the proof through the TurboVerifier
- If verification passes, the contract releases the corresponding assets from its L1 liquidity pool
This mechanism is critical for user sovereignty — it ensures that no single point of failure (the sequencer) can permanently trap user funds.
2.2 The RollupProcessor Contract Architecture
The RollupProcessorV3 contract served as the L1 anchor for Aztec Connect. Its core responsibilities included:
-
Receiving and processing rollup submissions: The
processRollup()function accepted encoded transaction data along with ZK proofs - Managing the rollup state: Maintaining the Merkle tree of all L2 balances
- Handling deposits and withdrawals: Processing user deposits into the L2 system and allowing withdrawals from verified L2 state
- Custodying L1 assets: Holding the actual ETH, DAI, wstETH, and other tokens that backed L2 balances
- Verifying proofs: Using the TurboVerifier to validate submitted ZK proofs
The processRollup() function was the critical entry point. It had to:
- Decode the submitted transaction data (
encodedInnerTxData) - Verify the accompanying ZK proof (via TurboVerifier)
- Update the rollup state (insert new notes into the Merkle tree)
- Execute L1 settlement (process deposits, withdrawals, and balance changes)
2.3 The Trust Boundary: Where Two Systems Must Agree
In a well-designed ZK rollup, there are two independent systems that must enforce identical constraints:
System A — The ZK Circuit (verified by TurboVerifier):
- Commits to a complete set of transaction data encoded in public inputs
- Inserts all decoded transaction notes into the rollup Merkle tree
- Proves that state transitions are valid according to the circuit's rules
System B — The L1 Settlement Logic (in Solidity, within processRollup()):
- Decodes the same transaction data
- Processes only a subset of transactions (determined by
numRealTxs) - Executes L1-level operations: deducting pending deposits, crediting withdrawals, validating signatures
The security model depends on these two systems having identical scope — they must process the exact same set of transactions. If System A commits to more transactions than System B validates, a gap opens where unverified operations can slip through.
2.4 The Critical Design Flaw
The vulnerability was in how the L1 settlement logic determined its processing scope. Specifically:
The ZK proof committed to N public input slots (all decoded transactions from encodedInnerTxData). The circuit inserted all N transaction notes into the Merkle tree.
But the L1 settlement logic only processed the first numRealTxs slots, where numRealTxs was a parameter that could be set independently by the caller.
The ZK circuit did not include a constraint gate enforcing:
numRealTxs == totalDecodedTransactionCount
Without this equality constraint, numRealTxs was effectively attacker-controlled. The attacker could set it to any value less than the total number of decoded transactions, creating a gap between what the proof committed to and what L1 settlement validated.
This is the trust boundary flaw: the system trusted the ZK proof for correctness of state transitions, but the proof's scope was not tightly bound to the settlement boundary. Two parts of the same system interpreted the same data differently.
3. On-Chain Fund Tracing
3.1 Attack Transaction Structure
The exploit was executed through 14 consecutive processRollup() calls within a single atomic transaction. This was a highly sophisticated, carefully planned operation.
Phase 1 — Creating Unbacked Balances (Rollup IDs 13277–13283):
In this phase, the attacker exploited the numRealTxs mismatch to create 7 unbacked L2 balances:
- The attacker set
numRealTxs = 1for each rollup submission - A non-actionable "dummy" transaction was placed in the first decoded slot (this was the only slot processed by L1 settlement)
- A real deposit transaction was placed in the second decoded slot
- The ZK proof accepted both slots and inserted both notes into the Merkle tree
- The L1 settlement only processed the first slot (the dummy), skipping the second slot entirely
- The second slot's deposit bypassed
decreasePendingDepositBalance()— no actual L1 assets were consumed - Result: The rollup state recorded a balance in the attacker's L2 account, but no corresponding L1 assets were deducted from the pool
This was repeated across 7 rollups for 7 different assets (ETH, DAI, wstETH, yvDAI, yvWETH, LUSD, yvLUSD).
Phase 2 — Withdrawal of Unbacked Balances (Rollup IDs 13284–13290):
Now the attacker had 7 unbacked L2 balances that appeared legitimate in the rollup state. To extract them:
- The attacker submitted 7 withdrawal proofs (one per asset)
- These proofs demonstrated the attacker's L2 balances (which had been created in Phase 1)
- The L1 settlement logic processed these withdrawals normally — it had no way to distinguish between legitimately deposited balances and the unbacked ones
- Real assets were drained from the RollupProcessor contract's L1 liquidity pool
The entire operation was atomic — if any step failed, the entire transaction would revert. The attacker structured it so that all 14 rollup calls were interdependent, ensuring complete execution.
3.2 BlockSec's Example: The DAI Deposit/Withdrawal Pair
BlockSec Phalcon used the first DAI deposit and withdrawal pair to illustrate the exploit mechanics:
Deposit (Phase 1):
-
numRealTxsset to 1 - Slot 1: Dummy transaction (processed by L1 settlement — no effect)
- Slot 2: DAI deposit of 270,513 DAI (inserted into L2 state by ZK proof, but NOT validated by L1 settlement)
- The
decreasePendingDepositBalance()function was never called for slot 2 - The rollup Merkle tree now contained a note showing the attacker's account had 270,513 DAI
Withdrawal (Phase 2):
- The attacker submitted a withdrawal proof for 270,513 DAI
- The proof referenced the note created in the deposit phase
- L1 settlement validated the proof and released 270,513 DAI from the contract's L1 balance
- No corresponding L1 asset had been deposited — this was an unbacked withdrawal
3.3 Post-Exploit Fund Movement
According to SlowMist's on-chain investigation:
- Stolen assets were first routed through an intermediate attack contract (deployed by the attacker as part of the exploit transaction)
- From the attack contract, funds were transferred to the attacker's EOA:
0x0f18…edd17 - As of the initial analysis window, all stolen assets remained in the attacker's wallet
- The attacker's wallet had been pre-funded through Tornado Cash, indicating operational security awareness and premeditation
- No immediate laundering activity was detected in the hours following the exploit
The use of Tornado Cash for initial funding suggests the attacker had planned this operation well in advance and took steps to obscure the origin of their capital.
4. Root Cause Analysis
4.1 Primary Root Cause: Missing Equality Constraint in the ZK Circuit
The fundamental vulnerability was the absence of an equality constraint gate in the ZK circuit that would have enforced:
numRealTxs == totalDecodedTransactionCount (from encodedInnerTxData)
This missing constraint allowed the L1 settlement boundary to diverge from the ZK proof's committed scope. The circuit verified that state transitions within the processed transactions were valid, but it did not verify that the settlement boundary covered all committed transactions.
In formal terms, the circuit's constraint system was:
- ✅ State transitions are correct for processed transactions
- ✅ Merkle tree updates are valid
- ✅ Proof structure is well-formed
- ❌ Missing: The number of transactions processed by L1 settlement equals the number committed by the proof
4.2 Secondary Root Cause: Missing Independent L1 Validation
The L1 settlement logic in processRollup() lacked independent verification mechanisms:
No total asset backing check: The contract never verified that the sum of all L2 balances was less than or equal to the L1 pool balance. If it had, the creation of unbacked balances in Phase 1 would have been detected.
No per-withdrawal source validation: When processing withdrawals, the contract trusted the rollup state without independently verifying that the withdrawing account's balance was backed by a legitimate deposit.
No cross-reference between deposits and balance creation: The contract did not maintain a ledger that could be cross-referenced to ensure every L2 balance had a corresponding L1 deposit event.
The system's security model relied on both the smart contract and the ZK circuit enforcing the same assumptions. When the circuit failed to constrain the unused slots, the L1 contract had no independent checks to detect the manipulation.
4.3 Contributing Factor: Post-Sunset Contract Upgrade
According to BlockSec's analysis, there is a notable detail regarding the timeline:
- Aztec's official sunset notice stated that the Aztec Connect rollup would continue processing transactions and withdrawals only until March 31, 2024
- After that date, the sequencer would stop running
- However, RollupProcessorV3 was still upgraded on April 10, 2024 (via PR 67) — after the official sunset date
This post-sunset upgrade did not appear to have undergone an external security audit before deployment. It is unclear whether this upgrade introduced the constraint gap or failed to address a pre-existing issue. Regardless, the fact that a deprecated contract was being modified without fresh audit scrutiny represents a significant governance failure.
4.4 The Immutable Contract Paradox
When Aztec Labs renounced admin keys, they made a philosophical statement: no central authority should be able to control or modify the protocol. This aligned with the privacy-first, censorship-resistant ethos of the project.
But this design choice created an irreversible risk:
- No emergency pause capability when the exploit was detected
- No ability to deploy a fix, even temporarily
- No mechanism to recover stolen funds
- Complete and permanent dependency on the original code's integrity
The immutability that protected users from censorship also protected the attacker from intervention. This is the immutable contract paradox — the same property that provides trustlessness also eliminates the possibility of emergency response.
This created what the industry has come to call a "zombie contract" — abandoned, funded, permanently vulnerable, and completely beyond anyone's ability to protect.
5. Defense Recommendations
5.1 For ZK Rollup Developers
Enforce Strict Boundary Matching
The most critical lesson is that L1 settlement verification scope must exactly match the public inputs committed by ZK proofs. Add explicit equality constraints in the circuit:
// This constraint must be enforced in the circuit
require(numRealTxs == decodedTxCount, "Settlement boundary mismatch");
Implement Independent L1 Validation Layers
Never rely solely on ZK proof verification for settlement. Implement independent L1 checks:
-
Total asset backing invariant:
sum(all_L2_balances) <= L1_pool_balance— check this before every withdrawal - Per-user withdrawal limits: Ensure no single withdrawal can exceed the user's verified deposit history
- Deposit source validation: Require that every L2 balance creation event corresponds to a verified L1 deposit transaction
Circuit Audit Scope Must Expand
Standard circuit audits should include:
- All constraint gates related to transaction counting and boundary enforcement
- Boundary consistency between proof scope and settlement scope
- Edge cases:
numRealTxs = 0,numRealTxs = 1,numRealTxs = totalDecoded - Cross-system invariant verification (circuit constraints vs. Solidity logic)
Calldata Decoding Consistency
Ensure that both the ZK circuit and the L1 contract decode calldata using identical logic and identical boundaries. Any divergence between these two paths is a potential exploit vector. Consider:
- Shared decoding libraries (if possible within circuit constraints)
- Formal verification that both paths produce identical outputs for identical inputs
- Differential testing: feed the same calldata to both paths and verify outputs match
5.2 For Deprecated Contract Management
Sunset Protocol Best Practices
For any protocol planning to deprecate a contract that holds user funds:
- Migrate all assets before deprecation — Set a hard deadline and actively communicate with remaining users
- If migration is not feasible — Implement a community-driven emergency mechanism (e.g., a time-locked multi-sig that can only withdraw funds to a predefined address)
- Conduct a final security audit — Specifically focused on the contract's post-deprecation state (no sequencer, no admin, but funds remain)
- Maintain a bug bounty program — Keep it active for at least 12 months post-sunset
- Deploy monitoring — Off-chain monitoring systems that can detect anomalous transactions and alert the community
The "Dead Man's Switch" Pattern
Consider implementing a dead man's switch for deprecated contracts:
- If no valid sequencer submissions occur for N days, the contract enters "emergency mode"
- In emergency mode, only direct withdrawals (with Merkle proofs) are allowed
- No new rollup submissions are accepted
- This prevents the exact attack vector used against Aztec Connect
5.3 For the Broader Ecosystem
Monitoring and Circuit Breakers
- Deploy community monitoring systems (like CertiK's real-time alerting)
- Implement governance-controlled circuit breakers activated by multi-sig
- Create shared threat intelligence feeds for common vulnerability patterns
- Standardize "zombie contract" risk assessment frameworks
Insurance and Recovery
- Encourage protocols to maintain insurance funds for deprecated systems
- Explore parametric insurance models that automatically pay out on verified exploits
- Develop standardized incident response playbooks for immutable contract exploits
6. Broader Context: The Rising Threat to Legacy Contracts
6.1 June 2026: A Month of Exploits
The Aztec Connect exploit was part of a troubling pattern in June 2026. According to DeFiLlama data:
- Humanity Protocol (June 8–9): ~$30M lost via compromised admin keys and bridge controls across Ethereum and BNB Chain
- Syscoin Bridge (June 7): $8M stolen via fake proof exploit
- Raydium AMM V3 (June 10): $1.34M stolen from 5 deprecated Solana liquidity pools
- TesseraDAO (June): $2.5M in a mint-and-dump attack on BNB Chain
- Aztec Connect (June 14–18): $2.19M from deprecated RollupProcessorV3
- ATM Token (June): $243,500 via hidden swap loophole on BNB Chain
Cumulative exploit losses in June 2026 exceeded $43.93 million by mid-month, with at least 12 separate incidents documented.
6.2 The Common Thread
The recurring pattern across these incidents:
- Abandoned infrastructure remains a critical attack surface
- Immutable contracts with remaining funds are permanent targets
- Post-deprecation upgrades without fresh audits introduce or preserve vulnerabilities
- Lack of migration leaves user assets exposed in systems with no operational oversight
Smart contracts on Ethereum are permanent. They cannot be deleted. If funded, they remain targets indefinitely. The Aztec Connect case demonstrates that even a 3-year-old deprecated contract can be a viable attack target.
7. Conclusion
The Aztec Connect exploit was not a breakthrough in cryptographic attacks or a novel zero-day in ZK proof systems. It was a trust boundary mismatch — a software engineering oversight where two system components interpreted the same data differently. The ZK proof committed to a broader transaction set than what L1 settlement validated, and the missing constraint gate in the circuit allowed the attacker to exploit this gap with surgical precision.
The $2.2M loss was preventable. A single equality constraint in the circuit — numRealTxs == totalDecodedTransactions — would have closed the vulnerability entirely. The fact that this was missed highlights the complexity of auditing systems at the intersection of circuit design and Solidity logic.
This incident provides three enduring lessons for the ZK rollup ecosystem:
- Proof verification alone is not sufficient — Settlement logic must independently validate all critical parameters and maintain cross-system invariants
- Deprecated does not mean safe — Immutable contracts with remaining funds are permanent, unpausable attack targets
- Sunset processes must be complete — Renouncing admin control without migrating funds or deploying monitoring creates irrecoverable risk
The broader DeFi community must take "zombie contract" risk seriously. Every deprecated protocol with remaining funds is a potential headline. The question is not whether another legacy contract will be exploited — it's when.
This analysis is based on on-chain data, security firm reports from BlockSec Phalcon, CertiK, and SlowMist, and publicly available information as of June 2026. The author is not affiliated with any of the mentioned entities. All on-chain addresses and transaction hashes are verifiable on Etherscan.
Follow for more Web3 security analysis and on-chain investigation.
Tags: #web3security #defi #ethereum #smartcontracts
Author: onchain-shadow




