Intent Circuit Design
Intent Circuit Design
The intent circuit is the foundational ZK constraint system used in SnarkSide to enforce the internal validity of a trade intent without revealing any of its contents. It encodes strict bounds on position size, leverage, slippage, and expiry, ensures cryptographic uniqueness via nullifiers, and constructs a final commitment hash used throughout the rest of the protocol.
This circuit is written in Circom, chosen for its performance, modularity, and broad compatibility with Groth16 proof systems. This section presents a detailed breakdown of the circuit implementation, discusses the rationale for each constraint, and explains how boundary violations are detected and rejected during proof generation.
Circuit Purpose
The intent circuit allows a trader to prove:
That their intended trade parameters fall within protocol-defined bounds.
That their margin commitment was properly constructed.
That their nullifier is unique and correctly derived.
That all inputs were composed into a deterministic Poseidon-based commitment hash.
This is proven in zero-knowledge and results in a compact SNARK that can be validated either by the off-chain relayer mesh or by an on-chain verifier contract during match settlement.
The output of the circuit is a single commitment hash, which is the canonical representation of the intent.
Circom Implementation
The following is a simplified but functionally complete version of the intent circuit, compatible with Circom 2.x:
template IntentCircuit(
MAX_NOTIONAL, // uint256: upper bound for trade size
MAX_LEVERAGE, // uint8: upper bound for leverage
MAX_SLIPPAGE, // uint256: upper bound for slippage
MAX_EXPIRY_BLOCK // uint64: maximum expiry window
) {
// Public output: final Poseidon commitment
signal output intent_commitment;
// Private inputs
signal input side; // 0 or 1
signal input notional_size; // uint256
signal input leverage; // uint8
signal input slippage; // uint256
signal input expiry; // uint64
signal input salt; // uint256
signal input margin_commitment; // field element
signal input nullifier; // field element
// --- Constraints on inputs ---
// Must be a valid direction
side * (1 - side) === 0;
// Notional size must be > 0 and <= MAX_NOTIONAL
notional_size >= 1;
notional_size <= MAX_NOTIONAL;
// Leverage must be >= 1 and <= MAX_LEVERAGE
leverage >= 1;
leverage <= MAX_LEVERAGE;
// Slippage must be >= 0 and <= MAX_SLIPPAGE
slippage >= 0;
slippage <= MAX_SLIPPAGE;
// Expiry block must be > current block and <= MAX_EXPIRY_BLOCK
// Note: actual expiry validation occurs during match time
expiry >= 1;
expiry <= MAX_EXPIRY_BLOCK;
// --- Poseidon commitment ---
// Combine all fields into a deterministic hash
component hasher = Poseidon(8);
hasher.inputs[0] <== side;
hasher.inputs[1] <== notional_size;
hasher.inputs[2] <== slippage;
hasher.inputs[3] <== leverage;
hasher.inputs[4] <== expiry;
hasher.inputs[5] <== salt;
hasher.inputs[6] <== margin_commitment;
hasher.inputs[7] <== nullifier;
intent_commitment <== hasher.output;
}This template is parameterized so that protocol-level maximums (e.g. max leverage) can be encoded at compile-time, minimizing runtime cost and ensuring uniformity across verifier deployments.
Input Constraints and Boundary Handling
Each input to the intent circuit is individually bounded. These constraints are hardcoded into the circuit and cannot be bypassed by the user.
Direction
Only two values are accepted for side: 0 (short) or 1 (long). The constraint:
side * (1 - side) === 0enforces that any non-0/1 value will fail the circuit.
Notional Size
While the system accepts any 256-bit input for notional_size, the circuit ensures that:
It must be strictly positive
It must not exceed a preset
MAX_NOTIONAL(e.g. 10⁶ * 10⁶ base units)
This protects against undercollateralized trades, arithmetic overflows in downstream match evaluation, and denial-of-service by invalid proof attempts.
Slippage
Traders may optionally specify a slippage cap. The circuit ensures it falls within system bounds. A slippage of zero is valid and indicates that the user will only accept execution at or better than their implied price commitment.
Slippage caps are enforced during off-chain matching as hard constraints, not suggestions.
Leverage
The leverage input is similarly bounded to prevent economically unviable or edge-case positions. This avoids excessive debt exposure on small-margin trades and simplifies downstream liquidation logic. Values outside the allowed range will cause proof generation to fail.
Expiry
The expiry value is specified as a block number relative to the L2 chain’s current state (or mocked block height in local dev environments). The circuit enforces that the expiry:
Is positive
Does not exceed a compile-time
MAX_EXPIRY_BLOCK
Expired intents are rejected by relayers without requiring proof regeneration.
Cryptographic Soundness
The use of Poseidon as the commitment function ensures:
Field compatibility with R1CS SNARKs
Collision resistance within the structured permutation
Constraint efficiency (Poseidon constraints per hash: ~170–220 depending on implementation)
Because all intent fields are included in the final commitment, the proof acts as a complete semantic envelope for the user’s trade request — without ever disclosing its contents.
Any alteration of a single field would result in a commitment mismatch and cause downstream proof failures during match verification.
Security Implications
The intent circuit plays a foundational role in SnarkSide’s safety model. A valid intent proof ensures:
No malformed orders enter the relayer system
Replay is impossible due to nullifier enforcement
Matching logic operates on known-good commitments
Settlement cannot be forged without constraint satisfaction
Additionally, since the circuit rejects overleverage, negative slippage, and invalid expiry ranges, economic denial-of-service through malformed proofs is cryptographically impossible.
Final Output
The intent_commitment emitted from the circuit becomes:
The canonical identifier for the intent
The input to the off-chain MPC matcher
A required part of the match circuit
The anchor for margin verification and vault insertion
The user need only submit the proof and the hash — nothing more is revealed, stored, or observable.
The intent circuit is not just a guardrail. It is the API contract between the trader and the protocol. It defines what participation means — and what must be proven to engage.
Its role is simple, but its enforcement is absolute.
Last updated

