Skip to content

collinsville22/Sable

Repository files navigation

Sable Logo

Sable — Permissionless BTC Yield Vaults on StarkNet

Multi-strategy BTC yield aggregator with ZK privacy, Smart DCA, CDPs, cross-chain bridging, and direct staking — all on StarkNet L2.

Next.js 16 · React 19 · Cairo · StarkNet · Groth16 · Tailwind v4

Live App · Documentation · Demo Video


Demo

Sable Demo Video

Watch the full demo on YouTube


Table of Contents


Architecture Overview

┌─────────────────────────────────────────────────────────────────────────┐
│                            USER BROWSER                                │
│  ┌─────────────┐  ┌──────────────┐  ┌───────────┐  ┌───────────────┐  │
│  │ Argent       │  │ Braavos      │  │ WalletCo- │  │  Local Note   │  │
│  │ Wallet       │  │ Wallet       │  │ nnect     │  │  Storage      │  │
│  └──────┬───────┘  └──────┬───────┘  └─────┬─────┘  └───────┬───────┘  │
│         └──────────────────┴───────────────┬┘                │          │
│                                            │                 │          │
│  ┌─────────────────────────────────────────┴─────────────────┴───────┐  │
│  │                    NEXT.JS 16 FRONTEND (App Router)               │  │
│  │                                                                   │  │
│  │  Pages:  /  /vault/[id]  /privacy  /dca  /cdp  /stake  /bridge   │  │
│  │          /portfolio                                                │  │
│  │                                                                   │  │
│  │  ┌─────────────────────────────────────────────────────────────┐  │  │
│  │  │                    REACT HOOKS LAYER                        │  │  │
│  │  │                                                             │  │  │
│  │  │  use-vault-data    use-vault-contract   use-shielded-vault  │  │  │
│  │  │  use-dca           use-cdp              use-staking         │  │  │
│  │  │  use-bridge        use-private-swap                         │  │  │
│  │  └──────────────────────────┬──────────────────────────────────┘  │  │
│  │                             │                                     │  │
│  │  ┌──────────────────────────┴──────────────────────────────────┐  │  │
│  │  │                    LIB / API LAYER                          │  │  │
│  │  │                                                             │  │  │
│  │  │  api/vaults    api/vesu     api/avnu    api/price           │  │  │
│  │  │  api/onchain   api/oneclick api/defillama                   │  │  │
│  │  │  privacy/note  privacy/prover  privacy/merkle               │  │  │
│  │  │  constants     format       rpc         abi/                │  │  │
│  │  └──────────────────────────┬──────────────────────────────────┘  │  │
│  └─────────────────────────────┼─────────────────────────────────────┘  │
│                                │                                        │
│  ┌─────────────────────────────┴──────────────────────────────────────┐ │
│  │                 NEXT.JS API ROUTES (Server-Side)                   │ │
│  │  /api/curator  /api/relayer/*  /api/dca/*  /api/shielded-deposit  │ │
│  │  /api/staking  /api/execute-outside                                │ │
│  └─────────────────────────────┬──────────────────────────────────────┘ │
└────────────────────────────────┼────────────────────────────────────────┘
                                 │
                    ┌────────────┴────────────┐
                    │    STARKNET MAINNET     │
                    │                         │
  ┌─────────────────┼─────────────────────────┼──────────────────────┐
  │                 │   SABLE CONTRACTS       │                      │
  │  ┌──────────┐  │  ┌──────────────────┐   │  ┌───────────────┐   │
  │  │ Sentinel │  │  │ Shielded Pool V4 │   │  │   DCA         │   │
  │  │ Citadel  │  │  │ (Groth16 ZK)     │   │  │   Contract    │   │
  │  │ Trident  │  │  ├──────────────────┤   │  ├───────────────┤   │
  │  │ Delta    │  │  │ Swap Pool        │   │  │   CDP         │   │
  │  │ Turbo    │  │  │ (Private Swaps)  │   │  │   Contract    │   │
  │  │ Apex     │  │  ├──────────────────┤   │  ├───────────────┤   │
  │  │          │  │  │ Stablecoin Vault │   │  │  Groth16      │   │
  │  │ (ERC4626)│  │  │ (Private USDC)   │   │  │  Verifier     │   │
  │  └────┬─────┘  │  └──────────────────┘   │  └───────────────┘   │
  │       │        │                          │                      │
  └───────┼────────┼──────────────────────────┼──────────────────────┘
          │        │                          │
  ┌───────┴────────┴──────────────────────────┴──────────────────────┐
  │                    EXTERNAL PROTOCOLS                            │
  │                                                                  │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────────┐ │
  │  │  Vesu    │  │  Ekubo   │  │  Endur   │  │  Nostra          │ │
  │  │ Lending  │  │ AMM/LP   │  │ Staking  │  │  CDP Lending     │ │
  │  └──────────┘  └──────────┘  └──────────┘  └──────────────────┘ │
  │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────────┐ │
  │  │  AVNU   │  │  Pragma  │  │  Garaga  │  │ NEAR 1-Click     │ │
  │  │ DEX Agg │  │  Oracle  │  │ ZK Proof │  │ Bridge/Intents   │ │
  │  └──────────┘  └──────────┘  └──────────┘  └──────────────────┘ │
  └──────────────────────────────────────────────────────────────────┘

Data Flow Summary

User Wallet ──► Frontend (React) ──► Hooks ──► StarkNet RPC ──► Smart Contracts
                     │                  │
                     │                  └──► External APIs (Vesu, AVNU, CoinGecko, DefiLlama)
                     │
                     └──► API Routes (Server) ──► Relayer / Curator / Keeper

Tech Stack

Layer Technology Version
Framework Next.js (App Router, Turbopack) 16.1.6
UI React 19.2.3
Language TypeScript 5.x
Styling Tailwind CSS 4.x
Animations Motion (Framer Motion) 12.6.3
Charts Recharts 2.15.3
Smart Contracts Cairo (Scarb) 2.14.0 / 2.13.1
Blockchain StarkNet Mainnet
StarkNet Client starknet.js 8.1.2
Wallet Integration @starknet-react/core 5.0.3
ZK Proofs (Groth16) snarkjs + circomlibjs 0.7.6 / 0.1.7
ZK Proofs (UltraHonk) @aztec/bb.js + @noir-lang/noir_js 0.82.2 / 1.0.0-beta.15
On-chain ZK Verify Garaga 1.0.1
Wallets Argent X, Braavos

Key Dependencies

{
  "starknet": "^8.1.2",
  "@starknet-react/core": "^5.0.3",
  "@starknet-react/chains": "^4.1.0",
  "snarkjs": "^0.7.6",
  "circomlibjs": "^0.1.7",
  "@aztec/bb.js": "0.82.2",
  "@noir-lang/noir_js": "1.0.0-beta.15",
  "garaga": "^1.0.1",
  "recharts": "^2.15.3",
  "motion": "^12.6.3",
  "clsx": "^2.1.1"
}

Feature Deep Dives

1. Vaults (/ and /vault/[id])

The core product: 6 distinct BTC yield strategies deployed as ERC-4626 tokenized vaults on StarkNet. Users deposit WBTC and receive share tokens representing their proportional claim on the vault's growing assets.

Vault Catalog

Vault Strategy Risk Cairo Contract Description
Sable Sentinel Pure Lending 1 (Low) sentinel.cairo Supply WBTC to Vesu PRIME pool. Simplest, safest strategy.
Sable Citadel Staked BTC + Lending 2 (Low-Med) citadel.cairo WBTC → Endur xWBTC liquid staking → supply to Vesu for dual yield.
Sable Trident Recursive Staking 3 (Med) trident.cairo 3x recursive WBTC staking loop on Endur for amplified staking rewards.
Sable Delta Neutral BTC-USDC Spread 4 (Med-High) delta_neutral.cairo Deposit WBTC as collateral → borrow USDC → deploy USDC to yield → earn spread.
Sable Turbo USDC Leverage Loop 5 (High) btcvault.cairo Leverage-loop WBTC collateral on Vesu: deposit → borrow USDC → swap to WBTC → re-deposit.
Sable Apex Multi-Strategy Max Yield 5 (High) apex.cairo 40% leverage lending + 35% Ekubo LP + 25% Endur staking. Maximum diversified yield.

ERC-4626 Vault Mechanics

Every Sable vault implements the ERC-4626 tokenized vault standard:

┌──────────────────────────────────────────────────┐
│                  ERC-4626 VAULT                  │
│                                                  │
│  deposit(assets) ──► mint(shares)                │
│  withdraw(assets) ◄── redeem(shares)             │
│                                                  │
│  share_price = total_assets() / total_supply()   │
│                                                  │
│  As strategy earns yield:                        │
│    total_assets ↑  →  share_price ↑              │
│    Each share redeems for more WBTC over time    │
└──────────────────────────────────────────────────┘

Deposit/Withdraw Flow

DEPOSIT:
  User ──► approve(WBTC, vault, amount)
       ──► vault.deposit(amount, receiver)
       ◄── vault mints share tokens to receiver
       ──► curator.deploy_idle() deploys WBTC into strategy

WITHDRAW:
  User ──► vault.withdraw(assets, receiver, owner)
       ──► vault unwinds strategy positions (may use flash loans)
       ◄── WBTC transferred to receiver
       ──► share tokens burned

Curator Pattern

The curator (owner) manages strategy execution. Idle WBTC sitting in the vault is deployed to yield protocols via the /api/curator endpoint:

Curator calls deploy_idle():
  1. Read idle WBTC balance in vault
  2. Execute strategy-specific deployment:
     - Sentinel: supply to Vesu PRIME
     - Citadel: stake on Endur → supply xWBTC to Vesu
     - Trident: recursive stake loop (3 iterations)
     - Delta Neutral: supply collateral → borrow USDC → deploy USDC
     - Turbo: leverage loop (deposit → borrow → swap → re-deposit)
     - Apex: split across lending + LP + staking
  3. All yield accrues to the vault → share price increases

Income Streams

Source Vaults Using It Description
Vesu Lending APY Sentinel, Citadel, Trident, Turbo, Apex Interest from borrowers on Vesu
Endur xWBTC Staking Citadel, Trident, Apex Liquid staking yield on BTC
BTCFi Season STRK All 100M STRK incentive program rewards
Ekubo LP Fees Apex Concentrated liquidity market making fees
Borrowing Spread Delta Neutral, Turbo Earn more on deployed capital than borrowing cost
Leverage Amplification Trident, Turbo Multiply base yield via recursive positions

Relevant Files

File Purpose
src/app/page.tsx Vault listing with filtering (Conservative/Moderate/Aggressive) and sorting (APY/TVL)
src/app/vault/[id]/page.tsx Vault detail page: strategy breakdown, APY analysis, metrics, deposit/withdraw
src/components/vault-card.tsx Summary card with APY, TVL, risk level, allocation bars
src/components/deposit-withdraw.tsx Deposit/withdraw modal with WBTC/USD toggle, max buttons
src/hooks/use-vault-data.ts Fetch vault metadata, APY breakdown, performance history
src/hooks/use-vault-contract.ts Read on-chain state: balance, share price, min deposit, strategy info
src/lib/api/vaults.ts Vault data fetching, APY calculation from multiple sources
src/lib/api/onchain.ts Call total_assets() on vault contracts via RPC
src/lib/api/vesu.ts Fetch Vesu pool APY, utilization, vToken data
src/lib/api/defillama.ts Historical APY/TVL charts from DefiLlama
src/components/performance-chart.tsx Historical APY/TVL chart (Recharts)

2. Privacy / Shielded Vaults (/privacy)

Zero-knowledge shielded deposits that break the on-chain link between depositor and withdrawer using Groth16 BN254 proofs verified on StarkNet via Garaga.

Privacy Tabs

Tab Pool Type Token Description
Lending Sentinel Vault WBTC Private deposits into Sable Sentinel (lending yield)
Yield Delta Neutral Vault WBTC Private deposits into Sable Delta Neutral (spread yield)
Stables Stablecoin Vault USDC Private USDC deposits into Vesu RE7 USDC Core
Swap Swap Pool WBTC→ETH/USDC/STRK Private token swaps via pool-to-pool transfers

How Shielded Deposits Work

DEPOSIT FLOW:
  1. User generates a random NOTE locally:
     ┌──────────────────────────────────────┐
     │  Note = {                            │
     │    secret:    random 31 bytes        │
     │    nullifier: random 31 bytes        │
     │    commitment: Poseidon(secret,      │
     │                        nullifier)    │
     │  }                                   │
     └──────────────────────────────────────┘

  2. User sends TX: approve(WBTC, pool, denomination) + pool.deposit(commitment)
     - Fixed denomination amounts (e.g., 0.0002 BTC, 0.0004 BTC)
     - Commitment is added to pending batch

  3. Relayer batches 3 deposits together:
     pool.process_batch([commitment_1, commitment_2, commitment_3])
     - All 3 commitments inserted into Merkle tree
     - Batch start index recorded

  4. Note saved to browser localStorage (CRITICAL: losing = losing funds)

WITHDRAWAL FLOW:
  1. User generates Groth16 proof locally (in browser via snarkjs WASM):
     ┌──────────────────────────────────────────────────────────┐
     │  Proof inputs:                                           │
     │    Private: secret, nullifier, pathElements, pathIndices │
     │    Public:  root, nullifierHash, recipient, relayer,     │
     │            fee, batchStart, batchSize                    │
     └──────────────────────────────────────────────────────────┘

  2. Proof submitted to relayer API (/api/relayer/withdraw)

  3. Relayer calls pool.withdraw(proof, publicInputs)
     - On-chain Groth16 verification via Garaga verifier contract
     - Nullifier hash recorded (prevents double-spend)
     - Funds sent to recipient address
     - Relayer fee deducted

  4. Recipient receives funds with NO on-chain link to depositor

Merkle Tree Structure

                    ROOT
                   /    \
                  /      \
              H(0,1)    H(2,3)
              /    \    /    \
            L0    L1  L2    L3     ◄── Leaf = Poseidon(commitment)
            │     │   │     │
          Note0 Note1 Note2 Note3

  - Tree depth: 20 levels (supports ~1M deposits)
  - Hash function: Poseidon (StarkNet-native, efficient in-circuit)
  - Batch size: 3 deposits per batch
  - Each withdrawal proves membership via Merkle path

Fixed Denominations (V4 Pools)

Sentinel (Lending):

Pool Key Denomination Pool Address
sentinel_1x 0.0002 BTC 0x002bdb9769851d0307e812351cc1eb31b617951fba786cfd5d58baff36589a33
sentinel_2x 0.0004 BTC 0x02a94630f46bcf7362c12ed5b0163b4dd7644eb923aaada61ffb858d7912e03d
sentinel_3x 0.0006 BTC 0x038224d3966b850913cfc4dd610032d8082e14c90fce91819a0fb994b1cc63f3
sentinel_4x 0.0008 BTC 0x06de0d6c46431628f0cd257aa4384125b2380a7c5362aab2b146283181c2dff3

Delta Neutral (Yield):

Pool Key Denomination Pool Address
dn_1x 0.00036 BTC 0x07298d2765e1dc61dae0f5d8c70b86e1857b038ab7a1f7c473111321aaac51aa
dn_2x 0.00072 BTC 0x059511116f7e1877fc9e3d26a2b9165d02cc367414c009c94b7b76f6d1e4c929
dn_3x 0.00108 BTC 0x01191727f6135bb878e9771066b0c6bcc18faed9146eb0a04eabb83190b90ce3
dn_4x 0.00144 BTC 0x040babfa49b967c7873e3b275b7f8d6bea88028854f5b5923c2de5af76d78c56

Stablecoin (Private USDC):

Pool Key Denomination Pool Address
stable_10 10 USDC 0x04f4af2cf01a1cf28f424ce2ce3d7fed7f11792c88e5ce7a3eedd21cea24a5eb
stable_25 25 USDC 0x05aa66a4541caf4d43a526edd89c0285a671e0be0024ae5f8ca9f6734f4b7c89
stable_50 50 USDC 0x03226cbb8976f41eddf88c2871cf4d04653a1b6415dee7037a1ceaf641e977a9
stable_100 100 USDC 0x06348e9e2db703841bed848146ef895c8aed4f3c143e76bd145d9b3c544cea68

Swap Input Pools:

Pool Key Denomination Pool Address
swap_1x 0.0002 BTC 0x0a9ca1d554d7ef360e47de70f89fefcb571b568c8dd049de96fa181e1c69c60
swap_2x 0.0004 BTC 0x06729a96665ddffa05443774414e550d95d473e87874b273f2ed7ae03bda5dca
swap_3x 0.0006 BTC 0x07f6e657c2cbe03a233890a7cda6d65f8d7dec65b7973ea9f3ef1f7307ffe1d8
swap_4x 0.0008 BTC 0x01046244f84287eaa49b06263739ac21a26b9e144db4e6799f571e0ce4141c46

Private Swap Flow

PRIVATE SWAP (WBTC → ETH/USDC/STRK):
  1. Deposit WBTC into swap input pool (shielded deposit)
  2. Generate withdrawal proof targeting the swap pool contract
  3. Swap pool receives WBTC, swaps via AVNU DEX
  4. Output token sent to recipient address
  5. No link between depositor and output recipient

  ┌──────────┐    ┌───────────────┐    ┌──────────┐    ┌──────────────┐
  │ Depositor│───►│ Swap Input    │───►│ Swap Pool│───►│ AVNU Router  │
  │ (hidden) │    │ Pool (ZK)     │    │ Contract │    │ (DEX swap)   │
  └──────────┘    └───────────────┘    └────┬─────┘    └──────┬───────┘
                                            │                 │
                                            │    ┌────────────┘
                                            ▼    ▼
                                      ┌──────────────┐
                                      │  Recipient   │
                                      │  (different  │
                                      │   address)   │
                                      └──────────────┘

ZK Circuit Versions

Version Proof System Verifier Status
V1 UltraHonk (Noir) @aztec/bb.js Legacy
V2 Groth16 BN254 snarkjs + Garaga Legacy
V3 Groth16 BN254 (6 public inputs) Garaga verifier 0x0410... Legacy
V4 Groth16 BN254 (7 public inputs) Garaga verifier 0x0332... Current

Relevant Files

File Purpose
src/app/privacy/page.tsx Privacy page with 4 tabs (Lending, Yield, Stables, Swap)
src/components/shielded-form.tsx Multi-pool shielded deposit form
src/components/private-swap-form.tsx Private swap execution interface
src/components/private-yield.tsx Yield pool info panel
src/components/private-stables.tsx Stablecoin pool info panel
src/components/private-swap.tsx Swap pool info panel
src/hooks/use-shielded-vault.ts Note generation, deposit, withdrawal, proof gen
src/hooks/use-private-swap.ts Private swap execution logic
src/lib/privacy/note.ts Shielded note: Poseidon hashing, nullifiers, commitments
src/lib/privacy/prover.ts Groth16 proof generation (snarkjs WASM)
src/lib/privacy/merkle.ts Merkle tree management
src/lib/privacy/calldata.ts Proof calldata serialization
contracts/src/shielded_pool_v4.cairo Current shielded pool contract
contracts/src/shielded_swap_pool.cairo Private swap pool contract

3. Dollar-Cost Averaging (DCA) (/dca)

Automated recurring BTC purchases with an intelligent Mayer Multiple strategy that adjusts buy amounts based on whether BTC is historically undervalued or overvalued.

How It Works

CREATE ORDER:
  User selects:
    - Sell token (USDC, USDT, ETH, STRK)
    - Amount per order (e.g., 10 USDC)
    - Frequency (Daily / Weekly / Bi-weekly / Monthly)
    - Number of orders (e.g., 4)
    - Strategy: Standard (fixed amount) or Smart (Mayer Multiple adjusted)

  For Smart DCA:
    - Total deposit = amount_per_order × num_orders × 1.5
    - The 1.5x buffer covers worst-case (all orders at max multiplier)
    - Unused funds refunded on completion or cancellation

EXECUTE ORDER (Keeper Bot):
  Every interval, the keeper bot:
    1. Checks which orders are due (block timestamp ≥ next_execution)
    2. For Smart DCA, queries Pragma Oracle for:
       - Current BTC price
       - 200-day TWAP (Time-Weighted Average Price)
       - Calculates Mayer Multiple = price / twap_200d
    3. Applies multiplier to base amount
    4. Fetches AVNU swap quote (sell token → WBTC)
    5. Calls dca.execute_order(order_id, routes, ...)
    6. Contract verifies timing, executes AVNU swap, records execution

Smart DCA — Mayer Multiple Strategy

The Mayer Multiple is the ratio of BTC's current price to its 200-day moving average. When the multiple is low, BTC is historically cheap — buy more. When high, it's overheated — buy less.

Mayer Multiple Market Signal Buy Multiplier Example (10 USDC base)
< 0.8 Deeply undervalued 1.5x 15 USDC
0.8 – 1.0 Undervalued 1.25x 12.50 USDC
1.0 – 1.5 Fair value 1.0x 10 USDC
1.5 – 2.0 Overvalued 0.75x 7.50 USDC
> 2.0 Extremely overvalued 0.5x 5 USDC

1.5x Deposit Buffer

Smart DCA deposits amount × orders × 1.5 upfront because:

  • Worst case: every single order executes at MM < 0.8 (1.5x multiplier)
  • Total spent = amount × orders × 1.5
  • If market stays fair value (1.0x), total spent = amount × orders
  • Remaining amount × orders × 0.5 is refunded on completion
Example: 10 USDC × 4 orders × 1.5 = 60 USDC deposited
  Order 1: MM=0.76 → 15 USDC spent (1.5x)   │ Running: 15/60
  Order 2: MM=1.12 → 10 USDC spent (1.0x)    │ Running: 25/60
  Order 3: MM=0.95 → 12.50 USDC spent (1.25x)│ Running: 37.50/60
  Order 4: MM=1.80 → 7.50 USDC spent (0.75x) │ Running: 45/60
  ──────────────────────────────────────────────
  Total spent: 45 USDC    Refunded: 15 USDC

DCA Contract Flow

┌──────────┐     approve + create_order      ┌─────────────┐
│   User   │ ──────────────────────────────► │ DCA Contract │
│          │                                  │              │
│          │     cancel_order (refunds)       │  Orders[]    │
│          │ ◄────────────────────────────── │  Executions[]│
└──────────┘                                  └──────┬───────┘
                                                     │
                  execute_order(routes)               │
┌──────────┐ ────────────────────────────────────────┘
│  Keeper  │          │
│   Bot    │          ▼
│          │    ┌─────────────┐    ┌──────────────┐
│(off-chain│    │ Pragma      │    │ AVNU Router  │
│ cron job)│    │ Oracle      │    │ (DEX swap)   │
└──────────┘    │ (BTC/TWAP)  │    │              │
                └─────────────┘    └──────────────┘

Relevant Files

File Purpose
src/app/dca/page.tsx DCA page with order creation form + active orders display
src/components/dca-form.tsx Order creation UI (token select, amount, frequency, strategy toggle)
src/hooks/use-dca.ts Order fetching, creation, display helpers (formatTokenAmount, getTokenSymbol)
scripts/dca_keeper.mjs Off-chain keeper bot: checks due orders, fetches AVNU quotes, executes
contracts/src/dca.cairo On-chain DCA contract: order storage, execution logic, Mayer Multiple calc
src/lib/api/avnu.ts AVNU DEX quote/build API integration

4. Collateralized Debt Position (CDP) (/cdp)

Borrow USDC against WBTC collateral via Nostra lending protocol. Users maintain a health factor above 1.0 to avoid liquidation.

CDP Parameters

Parameter Value
Collateral Token WBTC (8 decimals)
Debt Token USDC (6 decimals)
Max LTV 70%
Liquidation Threshold ~75% (Nostra parameter)
Backend Protocol Nostra Finance
Collateral Token (Nostra) iWBTC-c (0x05b7...f0c)
Debt Token (Nostra) dUSDC (0x063d...a51)

CDP Lifecycle

OPEN POSITION:
  1. User approves WBTC to CDP contract
  2. CDP.deposit_collateral(amount)
     ├── Transfers WBTC from user
     ├── Approves WBTC to Nostra CDP Manager
     └── Deposits as iWBTC-c collateral on Nostra

  3. CDP.borrow(amount)
     ├── Borrows USDC from Nostra against collateral
     └── Transfers USDC to user

MANAGE POSITION:
  Health Factor = (collateral_value × liquidation_threshold) / debt_value

  ┌────────────────────────────────────────────────┐
  │  Health Factor    │  Status                    │
  │  > 2.0            │  Very Safe (green)         │
  │  1.5 – 2.0        │  Safe (green)              │
  │  1.0 – 1.5        │  Caution (yellow)          │
  │  < 1.0            │  LIQUIDATION RISK (red)    │
  └────────────────────────────────────────────────┘

REPAY + WITHDRAW:
  1. CDP.repay(amount)
     ├── User approves USDC to CDP contract
     ├── Repays USDC debt on Nostra
     └── Reduces outstanding debt

  2. CDP.withdraw_collateral(amount)
     ├── Withdraws iWBTC-c from Nostra
     └── Returns WBTC to user

CLOSE POSITION (Atomic):
  CDP.close_position()
  ├── Calculates total debt (principal + accrued interest)
  ├── User approves USDC to cover full debt
  ├── Repays 100% of debt to Nostra
  ├── Withdraws 100% of collateral from Nostra
  └── Returns all WBTC to user
  (Single transaction, no partial state)

Liquidation Price Calculation

liquidation_price = (debt_usdc × 100) / (collateral_wbtc × max_ltv)

Example:
  Collateral: 0.001 WBTC
  Debt: 50 USDC
  Max LTV: 70%

  Liquidation price = (50 × 100) / (0.001 × 70) = $71,428
  If BTC drops below $71,428, position can be liquidated

Relevant Files

File Purpose
src/app/cdp/page.tsx CDP page with position management
src/components/cdp-form.tsx Deposit, borrow, repay, withdraw, close position UI
src/hooks/use-cdp.ts Fetch CDP positions, protocol stats, health factor calc
contracts/src/cdp.cairo On-chain CDP contract (Nostra integration, close_position)
src/lib/abi/cdp.ts CDP contract ABI

5. Staking (/stake)

Direct WBTC staking into Vesu lending pools for yield + STRK rewards.

Available Pools

Pool Vesu Pool ID vToken Yield Source
Vesu PRIME 0x0451fe...c3b5 vWBTC (0x04ecb0...f56c) Base lending APY + BTCFi STRK
Re7 xBTC 0x03a841...8ecf vWBTC-Re7xBTC (0x0131cc...52a0) Endur staking + lending APY + STRK

Staking Flow

STAKE:
  1. User approves WBTC to Vesu Singleton
  2. Vesu Singleton.supply(pool_id, WBTC, amount)
  3. User receives vToken (interest-bearing)
  4. vToken balance grows over time as interest accrues

UNSTAKE:
  1. User calls Vesu Singleton.withdraw(pool_id, vToken, amount)
  2. vToken burned, WBTC returned (more than originally deposited)

Relevant Files

File Purpose
src/app/stake/page.tsx Pool listing with APY and TVL
src/app/stake/[pool]/page.tsx Individual pool management
src/components/staking/pool-card.tsx Pool summary card
src/components/staking/stake-form.tsx Stake/unstake interface
src/hooks/use-staking.ts Fetch pool data and user positions from Vesu API
src/lib/abi/vesu-singleton.ts Vesu Singleton ABI

6. Cross-Chain Bridge (/bridge)

Bridge assets to/from StarkNet via NEAR Intents / 1-Click protocol. Supports Solana, Ethereum, Base, Arbitrum, NEAR, and other chains.

Bridge Architecture

BRIDGE IN (External Chain → StarkNet):
  ┌──────────┐    deposit     ┌──────────────┐    intents    ┌──────────┐
  │ Solana / │ ─────────────► │ NEAR 1-Click │ ────────────► │ StarkNet │
  │ Ethereum │    (SOL/ETH)   │ Protocol     │    (swap +    │ Wallet   │
  │ Base ... │                │ (Intents)    │    bridge)    │ (STRK)   │
  └──────────┘                └──────────────┘               └──────────┘

BRIDGE OUT (StarkNet → External Chain):
  ┌──────────┐   STRK transfer  ┌──────────────┐   intents   ┌──────────┐
  │ StarkNet │ ────────────────► │ NEAR 1-Click │ ──────────► │ Solana / │
  │ Wallet   │   to deposit     │ Protocol     │   (swap +   │ Ethereum │
  │          │   address        │ (Intents)    │   bridge)   │ etc.     │
  └──────────┘                  └──────────────┘              └──────────┘

Bridge Flow

1. User selects source chain + token, destination chain + token
2. Frontend fetches 1-Click quote (dry run) for estimated output
3. User confirms → non-dry quote → deposit address generated
4. Bridge IN: User sends tokens to deposit address on source chain
   Bridge OUT: Frontend submits STRK transfer to 1-Click deposit address
5. Frontend polls 1-Click status endpoint for completion
6. On completion: tokens arrive at destination

Relevant Files

File Purpose
src/app/bridge/page.tsx Bridge page
src/components/bridge/bridge-form.tsx Bridge direction toggle, chain/token selectors, amount input
src/components/bridge/bridge-tracker.tsx Step-by-step bridge status tracker
src/components/bridge/chain-token-selector.tsx Chain and token picker UI
src/hooks/use-bridge.ts Bridge logic: quotes, execution, polling, session persistence
src/lib/api/oneclick.ts 1-Click / NEAR Intents API integration

7. Portfolio (/portfolio)

Unified dashboard showing all user positions across every Sable product.

Tracked Positions

Category Data Shown
Vault Positions Share balance, current value, unrealized PnL per vault
Staking Positions vToken balance, staked amount, earned rewards
CDP Positions Collateral value, debt value, health factor, liquidation price
DCA Orders Active orders, executed count, total bought, refundable amount
Shielded Notes Number of active notes (from localStorage), denomination, pool

Relevant Files

File Purpose
src/app/portfolio/page.tsx Unified portfolio dashboard

Smart Contracts Deep Dive

All contracts are written in Cairo and compiled with Scarb 2.13.1+ targeting Cairo 2.14.0.

Contract Inventory

Contract File LOC (approx) Purpose
Sentinel Vault sentinel.cairo ~500 Pure Vesu PRIME lending
Citadel Vault citadel.cairo ~600 Endur staking + Vesu lending
Trident Vault trident.cairo ~700 3x recursive staking loop
Delta Neutral Vault delta_neutral.cairo ~800 Collateral → borrow USDC → deploy yield
Turbo Vault (Base) btcvault.cairo ~900 Leverage loop (WBTC → borrow → swap → repeat)
Apex Vault apex.cairo ~1000 40% lending + 35% Ekubo LP + 25% Endur
DCA dca.cairo ~600 Recurring orders with Mayer Multiple
CDP cdp.cairo ~500 Nostra-backed WBTC→USDC borrowing
Shielded Pool V4 shielded_pool_v4.cairo ~800 Groth16 ZK deposits/withdrawals
Shielded Pool V3 shielded_pool_v3.cairo ~700 Previous version (batched deposits)
Shielded Pool V2 shielded_pool_v2.cairo ~600 Fixed denomination pools
Shielded Pool V1 shielded_pool.cairo ~500 Legacy (Noir + UltraHonk)
Shielded Swap Pool shielded_swap_pool.cairo ~400 Pool-to-pool private swaps
Stablecoin Vault stablecoin_vault.cairo ~400 USDC yield via Vesu RE7 USDC
Strategy Interface strategy.cairo ~200 Shared strategy trait
Interfaces interfaces.cairo ~300 Shared interface definitions
Lib lib.cairo ~50 Module re-exports

Scarb Configuration

[package]
name = "sable"
version = "0.1.0"
edition = "2024_07"
cairo-version = "2.14.0"

[dependencies]
starknet = "2.14.0"
openzeppelin = "..."  # ERC20, ERC4626, Ownable, Upgradeable
garaga = "..."        # Groth16 BN254 verification

Contract Patterns

ERC-4626 (Vault Contracts): All 6 vault contracts implement the ERC-4626 standard with:

  • deposit(assets, receiver) / mint(shares, receiver)
  • withdraw(assets, receiver, owner) / redeem(shares, receiver, owner)
  • total_assets() — returns total WBTC managed including deployed capital
  • convert_to_shares(assets) / convert_to_assets(shares)

Ownable + Upgradeable:

  • owner() — curator/deployer address
  • upgrade(new_class_hash) — replace contract implementation
  • All strategy execution is owner-gated

Flash Loan Unwind: Complex strategies (Turbo, Trident, Apex) may require flash loans for withdrawal:

  • Borrow WBTC → repay debt → withdraw collateral → repay flash loan
  • Ensures atomic unwinding of leveraged positions

Protocol Integrations

Vesu V2 — Lending/Borrowing

Sable's primary yield source. Vesu is a modular lending protocol on StarkNet.

Integration Usage
Supply WBTC Sentinel, Citadel (via xWBTC), Turbo leverage
Supply USDC Stablecoin Vault (RE7 USDC Core pool)
Borrow USDC Delta Neutral, Turbo (leverage loop)
vTokens Interest-bearing receipts for staking page
Pool API APY, utilization, TVL data for frontend

Contract: Vesu Singleton 0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160

AVNU — DEX Aggregation

Integration Usage
DCA Execution Keeper swaps sell token → WBTC via AVNU routes
Turbo Loop Swap borrowed USDC back to WBTC
Private Swap Swap WBTC → output token in swap pool
API Quote + build swap calldata

Contract: AVNU Router 0x04270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f

Ekubo — Concentrated Liquidity

Integration Usage
Apex Vault 35% allocation to WBTC-ETH or WBTC-USDC LP
LP Fees Market making revenue

Endur — Liquid Staking

Integration Usage
Citadel Vault Stake WBTC → receive xWBTC (liquid staking token)
Trident Vault 3x recursive stake loop
Apex Vault 25% allocation to Endur staking

Nostra — CDP Lending

Integration Usage
CDP Contract Backend for WBTC→USDC borrowing
iWBTC-c Collateral token on Nostra
dUSDC Debt token on Nostra

Contract: Nostra CDP Manager 0x073f6addc9339de9822cab4dac8c9431779c09077f02ba7bc36904ea342dd9eb

Pragma — Price Oracle

Integration Usage
DCA Smart Orders BTC spot price + 200-day TWAP for Mayer Multiple
CDP BTC price for health factor / liquidation price display

Contract: 0x2a85bd616f912537c50a49a4076db02c00b29b2cdc8a197ce92ed1837fa875b

Garaga — ZK Verification

Integration Usage
Shielded Pools On-chain Groth16 BN254 proof verification
Poseidon Hashing StarkNet-native hash for note commitments

Verifier Contracts:

  • V3: 0x041011d7912b6759f2fe3cc66a1f746b81ec012c2774adabc77eecc299e0878d
  • V4: 0x03329c4d5c2e37dfd20d46c3c20be9230b2152c71947ead441c342d989d52ffa

NEAR Intents / 1-Click — Cross-Chain Bridge

Integration Usage
Bridge IN External chain → STRK on StarkNet
Bridge OUT STRK on StarkNet → external chain
Supported Chains Solana, Ethereum, Base, Arbitrum, NEAR, Polygon, Avalanche

Contract Addresses (Mainnet)

Sable Protocol Contracts

Contract Address Voyager
Sentinel Vault 0x04ec7fdb1679450fb88eae9facc439a46be4ddeba628211e269a7467f6e0971b View
Citadel Vault 0x077ad8d0fe4b946cedc02eb8eb61a64e85bcde802a83e879e8c68fed8b9b130e View
Trident Vault 0x058aadc9db62700de03d89a7c8f2952851d94e75f854cc6a340ef92d00cd3fb8 View
Delta Neutral Vault 0x06c8779ee7ed14b35ac5c6eae5dc721cc3e8104a65ffef4b5252babc407a1012 View
Turbo Vault 0x05f3d02005027296ccfb90574544b941d9ddc55c673e6fe0e92cb6f07e68d1f7 View
Apex Vault 0x071eb7fc3a912c0ee85b1dc795e29fd77ff4203a33384a1171dd4fcb7c7b3df9 View
DCA 0x0730f5de50171590132ff9238859d7eccbfa8359393f52083b3b88b397955e56 View
CDP 0x042f0f1cbb5ce44cc411f608d3c8295f3816ef7c3b6764cd6e46463efc7ca499 View
Stablecoin Vault 0x070fc554c4a9714646c5f53aea26611a70c529133a34c00f2b8f95fd2cba742d View
Shielded Swap Pool 0x059abf82e0bc584a3b4e94fcc5aa4b5f7e9ea946b5fbe236cdecf491ad0b2c72 View

Token Addresses

Token Address Decimals
WBTC 0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac 8
ETH 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 18
USDC 0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8 6
USDT 0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8 6
STRK 0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d 18

Vesu Pool Addresses

Pool Pool ID
PRIME 0x0451fe483d5921a2919ddd81d0de6696669bccdacd859f72a4fba7656b97c3b5
Re7 xBTC 0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf
Re7 USDC Core 0x03976cac265a12609934089004df458ea29c776d77da423c96dc761d09d24124

External Protocol Addresses

Protocol Contract Address
Vesu Singleton Lending Pool Manager 0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160
AVNU Router DEX Aggregator 0x04270219d365d6b017231b52e92b3fb5d7c8378b05e9abc97724537a80e93b0f
Nostra CDP Manager Lending Backend 0x073f6addc9339de9822cab4dac8c9431779c09077f02ba7bc36904ea342dd9eb
Pragma Oracle Price Feed 0x02a85bd616f912537c50a49a4076db02c00b29b2cdc8a197ce92ed1837fa875b
Groth16 Verifier V4 ZK Proof Verifier 0x03329c4d5c2e37dfd20d46c3c20be9230b2152c71947ead441c342d989d52ffa
Groth16 Verifier V3 Legacy ZK Verifier 0x041011d7912b6759f2fe3cc66a1f746b81ec012c2774adabc77eecc299e0878d

API Routes

All API routes are implemented as Next.js Route Handlers (server-side).

Route Method Purpose
/api/curator POST Curator deploys idle vault funds into yield strategies
/api/shielded-deposit POST Submit shielded deposit with Groth16 proof to pool
/api/dca/quote GET Get AVNU swap quote for DCA execution
/api/dca/build POST Build DCA swap transaction calldata
/api/relayer/fee-estimate GET Estimate relayer fee for private withdrawal
/api/relayer/pool-status GET Get shielded pool Merkle tree status (root, size)
/api/relayer/withdraw POST Submit private withdrawal with Groth16 proof
/api/relayer/deploy-batch POST Deploy batch of pending shielded deposits
/api/relayer/private-swap POST Execute private swap between pools
/api/staking GET Fetch staking pool data from Vesu API
/api/execute-outside POST Execute outside transactions (utility)

On-Chain Testing Evidence

All features have been tested on StarkNet Mainnet from the following wallet:

Tester Wallet

Address: 0x0362A762F25f0aa9C3935D4D11D5d5099262E4fF59f5D360d37BD157fBC3ABbc Account Type: Argent X Total Transactions: 98+

Vault Transactions

Sable Trident (0x058aadc9db...)

Action TX Hash Voyager
Deposit 0x63956529fd2a628b14e495cd41fc3d549874578ffc3613e8f22fd2914dff2ca View
Deposit 0x2752d9b62f3018abc665fa7a657517e5622ac80071dbb78cfddee3530e6b08b View
Deposit 0x931d14aea50bdded3932ce27338776421029a65d7895a65a2b2c39ac6bdb96 View
Deposit 0x4e5382f310d35dbdf83b6f25200f3ca2a8486ed3c2fb75b59ad8f4e0daec1d9 View
Withdraw 0x3469f3cc5a2c9cd70b6e4917bf93e4887738fe21ae5ced1f2fa3750bb2a3d1a View
Withdraw 0xea31a445785525edf6e88db39970bc33c67ffcfe5e33099b7dff266d49b18b View
Withdraw 0x226bdf395d1583c1037ed9c30c719672d570f95e3467936991ed1c4983272a4 View
Withdraw 0x2000617912e63a01b1eee025a4b1e7af7faca2816d8a4e96a285800ff46b546 View
Withdraw 0x724110ca31468d5bdfbf303d7abd6ce7ae087c23ba131cbebc500e03a7c13c5 View

Sable Citadel (0x077ad8d0fe...)

Action TX Hash Voyager
Deposit 0x30e3f2b57afee22c47df45c1841d379d736bf01962a813c79fa55d113f6d166 View
Deposit 0x7b1f475268fce4487490c250be68d10c22878086c890e6454abdff3a3f15ba3 View
Deposit 0x250e748bf6ff67f2e0ea2453235abccb6311f57dce5f8906a3b486a194434ea View
Withdraw 0x640f97cc1ca4d8e547518e6e52ffa5ccdd01a170a8bfca8a2e8ca2c90e99f74 View
Withdraw 0x360efe165b08f72343142e2d2c9294086130125e143cdd3222d5bc8a5781774 View

Sable Turbo (0x05f3d02005...)

Action TX Hash Voyager
Deposit 0x7886dd70b823481d91cc8545f3092596f215cec8a7b26cc7f3260ddac47a4f View
Deposit 0xf8b68d9735f2b668e08eb8ce237a36bc847c90dd2eea60cbd81efd9486c5e8 View
Deposit 0x50fb6cf22f7dac6c94c26f1c1b1f3b7265073828fa71fb05abc91365837884d View
Deposit 0x78298f47a1bf0787d6cafe9d25a274d7e82ffd48b02aaf0db11a7dcbf6d86f9 View
Deposit 0x6abe965bdc657df2ffd5f932742da844acd8f15ceb0dd2fc763ceeba24f889f View
Withdraw 0x4f18fec0125aafb635288c9ff80daf7c9a8ac642db315a03907f9de3a82c868 View
Withdraw 0x7507bea73cf503eac93d58870d33cec4923f9886d7cc6a72c6e795b1b9ffb7d View
Withdraw 0x5cb3acf6463e064e06a50010c14b4f1ceabd02bbdfd864c2cec15aa7aaa5a5c View
Withdraw 0x6d99b72eea9a6d6f9bef57096952e7a74035eeb8eb2d844a9a395da24e8ec50 View
Withdraw 0x4f6538863ede80861f1419c0d47652d557472ccac85d53a63dc4d0ab0c0454d View

Sable Apex (0x071eb7fc3a...)

Action TX Hash Voyager
Deposit 0x7cb531ec72ae7d2967c46e2b9e4f1617021b24cce3923041dd9449875e2fb33 View
Deposit 0x361444553f157da29b3cfdd95f4625bb4880455151e762153634ea15a89d857 View
Withdraw 0x489523c49a24cc3e5c45438c39caaf1ee06358217464540c06e7d71bb31ea96 View
Withdraw 0x35d936ce731b9661ed1800f62ccb38e62526e4356c420e5fac1b479b06759cc View
Withdraw 0x23cbfbaa54f5e83bfb904afcbc8ce3288e7c01bf154491567282df226c4f193 View

Sable Sentinel (0x04ec7fdb16...)

Action TX Hash Voyager
Deposit 0x274bbea8239ed28b9b1d717d485bac6cbf45e929e3fecdd01fa7c0f4a0bde9b View
Deposit 0x24b5eacf53c9ff8f2638c78a38dacec2443735cbd1365a45cfb8c4bdf0827ae View
Deposit 0x585846d1623c1f072f656ca8e54f6d7bd91c95d8bf9620d9ee38f13992915b5 View
Withdraw 0x278caa569b6835676371db7dea08a9bf418015833eb3507856fae21da053d3f View
Withdraw 0x480714ba02d56dd0ac609a20fc1a1773d0b78f1660dc1914b645d9fa30af6e9 View
Withdraw 0x7e69158b4f33cf43062a56584ce60a98df8ff96c306073ea2f60f4baebe724c View

Sable Delta Neutral (0x06c8779ee7...)

Action TX Hash Voyager
Deposit 0x5560c97ee17d49bba4b93bf1acfbc324bd25cab33051a6b90cc18249b3b517f View
Deposit 0x6e4566cd90cbe44771441722f82b8c5d8778b3da047c3a00746c15c6f8dfbea View
Deposit 0x5efbec7187a30fcfeb9248cfbaaf9b73f8e469103605c58e1b041b3507a8ac2 View
Withdraw 0x39ca51bfa3db16483f91fa171b29ee97a78e9b757e3026cb69e0914fb61cb1 View
Withdraw 0xafb521bacc40e445308191cfe4065de0b61ff600e739e2b1ea1d80e1b92481 View
Withdraw 0x5b7574b4cf306abe90e446d3cbed25a44fea78c9580bd25ba67e7b76f4ae040 View

Staking Transactions (Vesu vTokens)

Vesu PRIME vWBTC (0x04ecb0667...)

Action TX Hash Voyager
Stake (Deposit) 0x21e9d013b70cd1e185173a7409d47bf902efbdf9d69e60f9ab87d5bcde3b2af View
Stake (Deposit) 0x4b24b9dbbdc400f9b6fa8ca740c72b9a647d3267b622af8a93ceac1d6cfcdbb View
Unstake (Redeem) 0x21088e22c1edb28a51ccda531ef4b18f4eee56a19dca66ae6c8b56ec4d529d9 View
Unstake (Redeem) 0x31a46ae3d007e2d44c721b5b68dd7843c54b9f1977a0425c28efcef9b42fffd View

Vesu Re7 xBTC vWBTC (0x0131cc091...)

Action TX Hash Voyager
Stake (Deposit) 0x2fa9a54b15c8b01122d6a4662b2050e70ab33cb2672675f3f7bee1bea9ba81 View
Stake (Deposit) 0x51d5a16e5ecd769f3f665db00efe95d8396482bb96fedee2f8e451a3af3f35a View
Unstake (Redeem) 0x39bf229249211ea96c6213c7e67901b573116788ef98534013acbe30b3ee672 View
Unstake (Redeem) 0x6d7c0faf1570a808ffed9ea92096944f95489c128a6a5b8c60e0be445a5f4e6 View

CDP Transactions

Action TX Hash Voyager
Deposit Collateral + Borrow 0x67333902d51b445787f71927b65846b178522eb259f2cbc9e661cd9bd3c7386 View
Repay + Withdraw 0x2dc374d5bd8efa4c0284fa94c9c3e790180f62cca86122345e3423dcdf16bdd View

DCA Transactions

Action TX Hash Voyager
Create Order (approve USDC + create_order) 0x633aa87c3038b8090573d58f66284504dc6c097422b73702e885cf899974d6c View
Cancel Order 0x47c7df3fdd91a9f3c5f37327beb791dbcfc195828deda9e09adfc1da98261fc View

CDP Contract Upgrade

Action TX Hash / Class Hash
Upgraded CDP Class Hash 0x6fe37a984a5ef280cc8238ff418d52dd1cbbab3240d5fb722ae5aadff537ed
Upgrade TX 0x4f8bf1f06bd1041d3d2666cb59098beb272e67998b577bd2818e839af69aa50

AVNU Swap Transactions (Sample)

The tester wallet executed 19+ swaps via the AVNU Router for token conversions:

TX Hash Voyager
0x4686d85a958637c01731577f5f0b315d384b416ffa1655c2e2c3423dc75eb41 View
0x75356c745ec3fa51737ba4f9d8fe347bf44ed14ac621a7793e4c5ae3ddd7c74 View
0x65791bfe6ab019dbbf4ae5e1100f258000df36f34f0a1cc8462966f6c426b7e View
0x56c5204f8c246cfc08d2455fd80f513b1567f932ed35297f82f965553a22e4f View
0x6f539c05857b7086ab480d7f6025217f8d5cf655929abd91122e6e108078d27 View
... and 14 more

Deployer Account

Address: 0x0007842590942b769a203cfcb07540299b86e22ba05b6708b516ec04ca044ef7 Total Transactions: 408+ Deploy Account TX: 0x3947977f87e6bf1bd79180d4a6c5278da151a3cc8dc2d92bc4e0be02537861b


Directory Structure

btcvault/
├── contracts/                          # Cairo smart contracts (Scarb project)
│   ├── src/
│   │   ├── lib.cairo                   # Module re-exports
│   │   ├── interfaces.cairo            # Shared interface definitions
│   │   ├── strategy.cairo              # Common strategy trait
│   │   ├── sentinel.cairo              # Vault: Pure Vesu lending
│   │   ├── citadel.cairo               # Vault: Endur staking + Vesu
│   │   ├── trident.cairo               # Vault: 3x recursive staking
│   │   ├── delta_neutral.cairo         # Vault: BTC-USDC spread
│   │   ├── btcvault.cairo              # Vault: Turbo leverage loop
│   │   ├── apex.cairo                  # Vault: Multi-strategy max yield
│   │   ├── stablecoin_vault.cairo      # Vault: Private USDC yield
│   │   ├── dca.cairo                   # DCA: Recurring orders + Mayer Multiple
│   │   ├── cdp.cairo                   # CDP: WBTC→USDC borrowing
│   │   ├── shielded_pool.cairo         # Privacy V1: Noir + UltraHonk
│   │   ├── shielded_pool_v2.cairo      # Privacy V2: Groth16 + fixed denom
│   │   ├── shielded_pool_v3.cairo      # Privacy V3: Batched deposits
│   │   ├── shielded_pool_v4.cairo      # Privacy V4: Current (7 public inputs)
│   │   └── shielded_swap_pool.cairo    # Privacy: Pool-to-pool private swaps
│   ├── Scarb.toml                      # Cairo project config
│   ├── Scarb.lock                      # Dependency lock file
│   ├── scripts/                        # Deployment & upgrade scripts
│   │   ├── deploy.mjs
│   │   ├── deploy.sh
│   │   ├── upgrade.mjs
│   │   ├── upgrade-cdp.mjs
│   │   └── declare_and_upgrade.py
│   └── target/                         # Build artifacts (sierra, casm)
│
├── src/
│   ├── app/                            # Next.js App Router pages
│   │   ├── layout.tsx                  # Root layout (providers, header, styling)
│   │   ├── page.tsx                    # / — Vault listing
│   │   ├── globals.css                 # Tailwind v4 + custom styles
│   │   ├── vault/
│   │   │   └── [id]/
│   │   │       └── page.tsx            # /vault/[id] — Vault detail
│   │   ├── privacy/
│   │   │   └── page.tsx                # /privacy — Shielded vaults
│   │   ├── dca/
│   │   │   └── page.tsx                # /dca — Dollar-cost averaging
│   │   ├── cdp/
│   │   │   └── page.tsx                # /cdp — Collateralized debt
│   │   ├── stake/
│   │   │   ├── page.tsx                # /stake — Pool listing
│   │   │   └── [pool]/
│   │   │       └── page.tsx            # /stake/[pool] — Pool management
│   │   ├── bridge/
│   │   │   └── page.tsx                # /bridge — Cross-chain bridge
│   │   ├── portfolio/
│   │   │   └── page.tsx                # /portfolio — Unified dashboard
│   │   └── api/                        # Next.js API route handlers
│   │       ├── curator/
│   │       │   └── route.ts            # POST: Deploy idle funds
│   │       ├── shielded-deposit/
│   │       │   └── route.ts            # POST: Shielded deposit
│   │       ├── dca/
│   │       │   ├── quote/route.ts      # GET: AVNU quote
│   │       │   └── build/route.ts      # POST: Build swap TX
│   │       ├── relayer/
│   │       │   ├── fee-estimate/route.ts
│   │       │   ├── pool-status/route.ts
│   │       │   ├── withdraw/route.ts
│   │       │   ├── deploy-batch/route.ts
│   │       │   └── private-swap/route.ts
│   │       ├── staking/
│   │       │   └── route.ts            # GET: Vesu pool data
│   │       └── execute-outside/
│   │           └── route.ts
│   │
│   ├── components/                     # React components
│   │   ├── header.tsx                  # Top navigation bar
│   │   ├── wallet-button.tsx           # Argent/Braavos wallet connect
│   │   ├── vault-card.tsx              # Vault listing card
│   │   ├── deposit-withdraw.tsx        # Vault deposit/withdraw modal
│   │   ├── performance-chart.tsx       # APY/TVL historical chart
│   │   ├── shielded-form.tsx           # Shielded deposit form
│   │   ├── private-yield.tsx           # Yield pool info
│   │   ├── private-stables.tsx         # Stablecoin pool info
│   │   ├── private-swap.tsx            # Swap pool info
│   │   ├── private-swap-form.tsx       # Private swap execution
│   │   ├── dca-form.tsx                # DCA order creation
│   │   ├── cdp-form.tsx                # CDP position management
│   │   ├── bridge/
│   │   │   ├── bridge-form.tsx         # Bridge direction, amount, chain select
│   │   │   ├── bridge-tracker.tsx      # Step-by-step status tracker
│   │   │   └── chain-token-selector.tsx
│   │   ├── staking/
│   │   │   ├── pool-card.tsx           # Staking pool card
│   │   │   └── stake-form.tsx          # Stake/unstake interface
│   │   └── ui/
│   │       └── animated-number.tsx     # Animated counter component
│   │
│   ├── hooks/                          # React hooks (state + chain interaction)
│   │   ├── use-vault-data.ts           # Vault metadata, APY, performance
│   │   ├── use-vault-contract.ts       # On-chain vault state reads
│   │   ├── use-staking.ts              # Vesu staking pools + positions
│   │   ├── use-dca.ts                  # DCA orders, creation, display
│   │   ├── use-cdp.ts                  # CDP positions, health factor
│   │   ├── use-shielded-vault.ts       # ZK deposits, withdrawals, proofs
│   │   ├── use-private-swap.ts         # Private swap execution
│   │   └── use-bridge.ts              # Cross-chain bridge logic
│   │
│   ├── lib/
│   │   ├── constants.ts                # All addresses, pool configs, tokens
│   │   ├── types.ts                    # TypeScript interfaces
│   │   ├── format.ts                   # Number/currency formatting
│   │   ├── rpc.ts                      # StarkNet RPC URL config
│   │   ├── data.ts                     # Hardcoded vault data (fallback)
│   │   ├── api/
│   │   │   ├── vaults.ts              # Vault data + APY calculation
│   │   │   ├── onchain.ts             # total_assets() RPC calls
│   │   │   ├── vesu.ts                # Vesu API integration
│   │   │   ├── defillama.ts           # DefiLlama historical data
│   │   │   ├── price.ts               # CoinGecko BTC price (30s cache)
│   │   │   ├── avnu.ts                # AVNU DEX router integration
│   │   │   └── oneclick.ts            # 1-Click bridge API
│   │   ├── privacy/
│   │   │   ├── note.ts               # Poseidon commitments, nullifiers
│   │   │   ├── prover.ts             # Groth16 proof generation (WASM)
│   │   │   ├── merkle.ts             # Merkle tree management
│   │   │   ├── calldata.ts           # Proof calldata serialization
│   │   │   └── worker-threads-stub.ts # WASM worker stub (Turbopack)
│   │   └── abi/
│   │       ├── vesu-singleton.ts      # Vesu contract ABI
│   │       ├── erc4626.ts             # ERC-4626 vault ABI
│   │       └── cdp.ts                 # CDP contract ABI
│   │
│   └── providers/
│       └── starknet.tsx                # StarknetConfig + wallet providers
│
├── scripts/                            # Off-chain tooling
│   ├── dca_keeper.mjs                  # DCA keeper bot (execute due orders)
│   ├── deploy-account.mjs             # Account deployment utility
│   ├── query_vaults.py                # Vault query testing
│   └── ekubo_query*.py                # Ekubo analytics scripts
│
├── public/                             # Static assets
│   ├── logo-sable.png                 # Project logo
│   └── tokens/                        # Token icons (SVG)
│
├── package.json                        # Dependencies & scripts
├── tsconfig.json                       # TypeScript configuration
├── next.config.ts                      # Next.js config (WASM, Turbopack)
├── postcss.config.mjs                  # PostCSS with Tailwind v4
├── eslint.config.mjs                   # ESLint configuration
└── .env.local                          # Environment variables (not committed)

Development Setup

Prerequisites

  • Node.js ≥ 20.x
  • npm ≥ 10.x
  • Scarb ≥ 2.13.1 (for Cairo contract compilation)
  • StarkNet wallet (Argent X or Braavos browser extension)

Installation

git clone <repo-url> btcvault
cd btcvault
npm install

Environment Variables

Create .env.local:

# StarkNet RPC (optional — defaults to Lava free endpoint)
NEXT_PUBLIC_STARKNET_RPC=https://rpc.starknet.lava.build
STARKNET_RPC=https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_8/<your-key>

# Curator (for /api/curator endpoint)
CURATOR_PRIVATE_KEY=0x...
CURATOR_ADDRESS=0x...

# Keeper (for DCA keeper bot)
KEEPER_KEY=0x...
KEEPER_ADDR=0x...

Running the Development Server

npm run dev
# Opens http://localhost:3000 with Turbopack hot reload

Building for Production

npm run build
npm start

Compiling Cairo Contracts

cd contracts
scarb build
# Outputs Sierra + CASM to contracts/target/

Running the DCA Keeper Bot

node scripts/dca_keeper.mjs
# Checks all due DCA orders, fetches AVNU quotes, executes on-chain

Linting

npm run lint

Deployment & Scripts

Contract Deployment

Contracts are deployed using starknet.js scripts in contracts/scripts/:

# Declare + deploy a new contract
node contracts/scripts/deploy.mjs

# Upgrade an existing contract
node contracts/scripts/upgrade.mjs

# Upgrade CDP specifically (with proper resource bounds)
node contracts/scripts/upgrade-cdp.mjs

Resource Bounds (StarkNet V3 Transactions)

All StarkNet V3 transactions require explicit gas bounds:

const resourceBounds = {
  l1_gas:      { max_amount: 100000n,      max_price_per_unit: 100000000000000n },
  l2_gas:      { max_amount: 1000000000n,  max_price_per_unit: 100000000000n },
  l1_data_gas: { max_amount: 200000n,      max_price_per_unit: 100000000000000n },
};

For gas-heavy operations (AVNU swaps, DCA execution), L2 gas may need up to 1.2 billion (max allowed: 0x47868C00).

Keeper Bot Production Deployment

The DCA keeper bot should run as a persistent service (cron job or systemd):

# Run every 6 hours via cron
0 */6 * * * cd /path/to/btcvault && node scripts/dca_keeper.mjs >> /var/log/dca_keeper.log 2>&1

License

This project is licensed under the MIT License.


Built on StarkNet · Powered by Vesu, Ekubo, Endur, Nostra, AVNU, Pragma, Garaga, NEAR Intents

About

Multi-strategy BTC yield aggregator with ZK privacy, Smart DCA, CDPs, cross-chain bridging, and direct staking — all on StarkNet L2.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors