Full Report
Aztec Connect is a privacy zkRollup blockchain used for DeFi. One of the novel features is the ability to send funds between the contracts to the L1 privately. At a high level, here's how the protocol works: User submits a DeFi interaction deposit proof to the mempool. The proof keeps the identity private. The sequencer groups these interactions from the same protocol together then rolls them up to be sent. Once receiving the rollup proof, the smart contract on Ethereum will act on behalf of users to exchange and perform other operations. On the next rollup the sequencer completes special claim proofs, splitting the newly received tokens between users. The program is written using zero knowledge circuits. Because this runs over a finite field and not integers, this makes trivial math complicated to perform. Aztec Connect uses TurboPlonk to create the connected gates. How do these circuits work? Simple math properties over a finite field must be discussed first: Addition: Add a value and wrap around if necessary. Multiplication: Multiply a value and wrap around if necessary. Negation: Finding a value that is 0 within the finite field. For instance, if the field is length 5 and the value I have is 2, then the negation would be 2+3. Inverse: The element becomes 1 when multiplied by the original. 4*4=1 mod 5. Subtraction: Add in the negated element. Division: Multiplication by the inverse. There are two main parts to a gate: selectors and witness values. Selectors are choose by the circuit writer to define the logic of the circuit. The witness values are the intermediate states of the circuit. w values are connected together within the circuit. The gate turns into the following: qm * wl * wr + q1 * wl + q2 * wr + q3 * w0 + qc = 0 mod p If we wanted to show that y = 4x3 + 2, then we need two gates. First, wl * wr - w0 = 0 mod p and 4 * wl * wr - w0 + 2 = 0 mod p. All in all, we don't need to prove the computation - we need to prove the witness value. The amount should be user_output = total_output * (user_input/total_input) for a given trade. The variable user_input will be floored in most cases. So, the circuit tries for find the division reminder to give to the user as well. While trying to do this, they divided up the number into limbs (sections?). By doing this, the 1 to 1 correspondence over module p was lost! This means that any multiple of p for a given value was valid. On top of this, the constraints for the remainder did not exist. According to the authors of the post, this could have resulted in the sequencer to create proofs that would assign the depositor much less funds than they should receive. Overall, a good description on ZK circuits (which I don't fully get yet) and on missing constraints causing problems. Math is hard enough when there's no millions of dollars at stake. Good find!
Analysis Summary
# Vulnerability: Aztec Connect Deletion Proof Range Constraint Flaw
## CVE Details
- **CVE ID**: Not Assigned (Internal Bug Bounty Discovery)
- **CVSS Score**: Estimated 9.0 - 10.0 (**Critical**)
- **CWE**: CWE-682: Incorrect Calculation; CWE-20: Improper Input Validation (Missing Range Constraints in ZK Circuits)
## Affected Systems
- **Products**: Aztec Connect (Privacy-focused zkRollup)
- **Versions**: Production versions prior to October 3, 2022
- **Configurations**: Systems utilizing the DeFi interaction "claim proof" circuit.
## Vulnerability Description
The vulnerability existed within a core Zero Knowledge (ZK) circuit responsible for the "claim proof"βthe mechanism that calculates and distributes tokens to users after a Layer 1 DeFi interaction.
Technically, ZK circuits operate over **finite fields** (modulo a large prime $p$) rather than standard integers. To perform integer-like division and ratio calculations (e.g., $user\_output = total\_output * \frac{user\_input}{total\_input}$), the protocol divided large numbers into "limbs" (sections). However, the implementation failed to properly constrain these values:
1. **Loss of 1-to-1 Correspondence**: Because values were not properly range-constrained, a value could be represented by itself plus any multiple of the prime $p$.
2. **Missing Remainder Constraints**: The circuit did not enforce that the remainder of the division was smaller than the divisor.
This allowed a malicious prover (sequencer) to provide "witness" values that satisfied the mathematical gates of the circuit but represented incorrect, manipulated financial outcomes.
## Exploitation
- **Status**: PoC confirmed by researcher; responsibly disclosed via Immunefi. No known exploitation in the wild.
- **Complexity**: High (Requires deep understanding of TurboPlonk and finite field arithmetic).
- **Attack Vector**: Network (Specifically via a malicious sequencer or through the "escape hatch" mechanism).
## Impact
- **Confidentiality**: None.
- **Integrity**: **High**. A malicious sequencer could spoof the output of DeFi interactions, effectively stealing funds by assigning a user significantly fewer tokens than they were owed and redirecting the surplus.
- **Availability**: Low (The protocol was temporarily throttled/access-disabled during remediation).
## Remediation
### Patches
- **Official Patch**: Deployed on **October 3, 2022**.
- The fix involved implementing proper range constraints using `create_range_constraint` to ensure residuals and limbs stayed within expected integer bounds, preventing the "multiple of $p$" overflow exploit.
### Workarounds
- **Preventative Measures**: Immediately following the report (Sept 12, 2022), Aztec Labs disabled public access to the workflow/sequencer functions that could be used to exploit the issue until the patch was finalized.
## Detection
- **Indicators of Compromise**: Discrepancies between expected DeFi L1 returns and the L2 tokens minted/distributed in the claim proof.
- **Detection Methods**: Manual auditing of ZK circuit constraints. The vendor is developing automated tooling to detect "unconstrained values" and orphaned witness variables in `Barretenberg` (their backend).
## References
- **Original Disclosure**: [https://hackmd.io/@aztec-network/claim-proof-bug](https://hackmd.io/@aztec-network/claim-proof-bug)
- **Researcher**: lucash-dev via Immunefi Bug Bounty.