Circuit

Overview

This protocol uses a single circuit called Withdraw that is built with circom. It's the tool that allows a depositor to see if their generated witness data satisfies it's constraints. If the constraints are satisfied, the user can withdraw.

Signals & How they satisfy the constraints

  • User must provide a valid nullifier that generates:

    • A valid commitment leaf which can be used to successfully rebuild the tree and produce their provided root, given their provided path indices and elements can do this.

    • A valid unique nullifierHash that will be used to mark the withdraw as spent in the solidity withdraw() function.

  • User must provide a valid root that exists in the specific tree for the pool contract.

  • User must provide valid path indices and elements that can successfully regenerate the correct tree associated with their provided leaf and root.

  • User provided a recipient, gas, and fee value, this simply disallows tampering of these arguments during a withdraw.

Holistic Description

There is an unbreakable connection between the p (proof points) values and s (public signals) values.

During a call to withdraw() if you pass in a valid array p but tamper with any s values, the verifyProof() function from the solidity verifier properly returns false.

This connection between p and s exist because during proof generation we:

  1. Use a proving key specifically formed during the circuit's compilation

  2. Use a witness with ALL it's public & private signals that satisfy the circuit.

When we "cook" the final proof and output the p points, the s signals are explicitly "baked into" the points p.

The values p and s that produced a valid proof, which satisfies all of the withdraw.circomcircuits constraints (and smart contract checks) cannot be tampered with.

Last updated