Skip to content

Smart Contracts

Cairo contracts on Starknet handling on-chain state and verification.

Architecture

src/
├── lib.cairo                 # Entry points
├── clmm/
│   ├── swap.cairo           # Swap engine
│   ├── liquidity.cairo      # Position management
│   └── math/                # Q128.128 arithmetic
├── privacy/
│   ├── merkle_tree_bn254.cairo
│   └── nullifier.cairo
└── verifier.cairo           # Garaga interface

Entry Points

deposit

Shield tokens with a commitment:

cairo
fn deposit(
    token: ContractAddress,
    amount: u256,
    commitment: u256,
) -> u32  // leaf index

swap_shielded_v2

Private swap with ZK proof:

cairo
fn swap_shielded_v2(
    full_proof_with_hints: Span<felt252>,
    public_inputs: WithdrawPublicInputsV2,
    swap_params: SwapParams,
)

Flow:

  1. Verify proof (Garaga)
  2. Check nullifier unused
  3. Validate Merkle root
  4. Execute CLMM swap
  5. Create output commitment
  6. Mark nullifier spent

mint_shielded

Add liquidity privately:

cairo
fn mint_shielded(
    full_proof_with_hints: Span<felt252>,
    public_inputs: MintPublicInputsV2,
    tick_lower: i32,
    tick_upper: i32,
    liquidity_delta: u128,
    owner_commitment: felt252,
)

Position key: poseidon(owner_commitment, tick_lower, tick_upper)

burn_shielded / collect_fees_shielded

Remove liquidity or claim fees by proving knowledge of owner_secret.

CLMM Module

Swap Loop

Start → [Compute step in tick] → Hit boundary?
                                    ↓ Yes
                              [Cross tick, update liquidity]

                              [Continue until done]

Tick System

  • Prices discretized: price = 1.0001^tick
  • Positions define [tick_lower, tick_upper] range
  • Tick bitmap for O(1) next-tick lookup

Fee Accumulation

cairo
fee_growth_global_0: u256  // Token0 fees per liquidity
fee_growth_global_1: u256  // Token1 fees per liquidity

Privacy Module

BN254 Merkle Tree

  • Depth: 20 (~1M leaves)
  • Hash: BN254 Poseidon (Garaga compatible)
  • Root history for stale proof tolerance

Nullifier Registry

cairo
nullifiers: Map<(u128, u128), bool>  // nullifier_hash → spent

Proof Verification

Garaga Groth16 verifier validates:

  • 7 public inputs
  • ~200 byte proof
  • ~3ms verification time

Storage

cairo
struct Storage {
    // Pool
    sqrt_price: u256,
    current_tick: i32,
    liquidity: u128,

    // Privacy
    merkle_root: u256,
    nullifiers: Map<(u128, u128), bool>,

    // Positions (commitment-keyed)
    positions: Map<felt252, PositionInfo>,

    // Ticks
    ticks: Map<i32, TickInfo>,
    tick_bitmap: Map<i16, u256>,
}

Errors

cairo
INVALID_PROOF         // ZK proof failed
NULLIFIER_SPENT       // Double-spend attempt
INVALID_ROOT          // Stale Merkle root
SLIPPAGE_EXCEEDED     // Output below minimum
INSUFFICIENT_LIQUIDITY

Released under the MIT License.