Intent Schema
Intent Schema
In SnarkSide, a trade intent is a cryptographically constrained data structure that expresses a trader's willingness to participate in a perpetual position under defined limits. The intent does not reveal any parameters publicly — rather, it exists as a zero-knowledge provable object that can be matched off-chain and settled on-chain only when verified by a constraint system.
The schema is designed for expressiveness, anonymity, and proof efficiency. Its construction leverages Poseidon hashing for SNARK-friendly commitments, nullifier logic for replay protection, and a salted structure to prevent correlation across time or attempts.
This page provides a full technical breakdown of the data fields within an intent, their cryptographic treatment, and how they are composed into provable commitment hashes.
Intent Fields
Each trade intent is composed of both public and private components — though in practice, all values are kept private during submission, and only their correctness is proven in zero-knowledge.
The key fields are as follows:
side
uint8
0 = short, 1 = long
notional_size
uint256
Value of the position (blinded)
max_slippage
uint256
Tolerable price deviation (blinded)
leverage
uint8
Multiplicative leverage factor
expiry
uint64
Absolute block number after which the intent is invalid
salt
uint256
Randomized entropy for hash uniqueness
margin_commitment
PoseidonHash
Encrypted commitment to margin inputs
nullifier
PoseidonHash
Unique per-intent replay guard
intent_commitment
PoseidonHash
Final hash of the entire structure
The intent object is never stored on-chain in raw form. Instead, only the intent_commitment (along with a SNARK proof verifying its construction) is posted to the relayer network. On-chain, only the final match commitment — derived from two matching intents — is settled.
Poseidon Hashing in Intent Commitment
The Poseidon hash function is selected due to its performance in zkSNARK circuits — offering low constraint overhead and efficient recursive compatibility.
Each intent’s data is reduced to a single field element hash using the Poseidon sponge construction:
template IntentCommitment() {
signal input side;
signal input notional;
signal input slippage;
signal input leverage;
signal input expiry;
signal input salt;
signal input margin_commitment;
signal input nullifier;
signal output commitment_out;
component poseidon = Poseidon(8);
poseidon.inputs[0] <== side;
poseidon.inputs[1] <== notional;
poseidon.inputs[2] <== slippage;
poseidon.inputs[3] <== leverage;
poseidon.inputs[4] <== expiry;
poseidon.inputs[5] <== salt;
poseidon.inputs[6] <== margin_commitment;
poseidon.inputs[7] <== nullifier;
commitment_out <== poseidon.output;
}This commitment is the canonical identity of the intent. It is the only artifact retained post-proof. All downstream verification and matching operations reference this hash.
Because the salt is unique and random per intent, even identical trade parameters will generate different commitments — ensuring non-linkability.
Nullifier Logic
Nullifiers are critical to ensuring that each intent can only be matched once. They serve two primary functions:
Replay Protection: Prevent reuse of an identical trade intent commitment by malicious relayers or duplicated submission.
Match Finalization: Once an intent is used in a verified match, its nullifier is recorded in a global nullifier set on-chain. Future attempts to settle a trade containing the same nullifier will be rejected.
The nullifier is computed as:
nullifier = PoseidonHash(stealth_key, intent_salt)This structure ensures that the nullifier is:
Unique to the user
Cryptographically unlinkable to wallet address
Validatable inside a circuit without revealing the user’s identity
The stealth_key may be derived from an ephemeral zkWallet keypair, and the salt is not reused across intents. The nullifier is included in the proof of a matched intent and verified on-chain before the vault root is updated.
Margin Commitment
Margin input is never posted as a raw value. Instead, users prove that they have committed sufficient collateral by constructing a margin_commitment, which itself is a Poseidon hash of:
margin_commitment = PoseidonHash(deposit_amount, token_id, stealth_recipient)This allows the system to:
Validate margin availability during matching
Commit to a specific asset type without revealing it
Avoid preemptive liquidity tracking by adversaries
The margin commitment becomes part of the intent hash and must be re-proven at match time during vault integration.
Hash Composition and Integrity
All fields are structured and ordered before hashing. This ensures that malformed or ambiguous proofs cannot be constructed. For example, field ordering is rigidly enforced during intent creation to avoid commitment mismatch between user and verifier.
Each intent is paired with:
intent_hash: used for match proof constraintproof.wtns: the witness file proving internal consistencyvk.json: verification key embedded into the relayer batch engine
Only intents with valid witnesses and fresh nullifiers are admitted into the matching pool. Upon settlement, the proof of match must include both intent hashes, which are re-verified against their own internal field commitments.
Summary
The SnarkSide intent schema is the foundation of the protocol’s privacy and correctness model. By using Poseidon hash commitments and zero-knowledge proofs to encode constraint-bound trade declarations, the system achieves:
Stateless off-chain coordination
Non-revealing participation
Replay-resistant matching
Verifiable proof-based execution
The result is an infrastructure that supports real perpetual markets under cryptographic constraints, without requiring exposure of trade metadata, user identity, or on-chain interaction at intent submission time.
Last updated

