# Shinobi Cash > Crosschain privacy protocol powered by Privacy Pools and zero-knowledge proofs ## FAQ Frequently asked questions about Shinobi Cash. ### General #### What is Shinobi Cash? Shinobi Cash is a crosschain privacy protocol that enables private transactions across the Ethereum ecosystem. It uses Privacy Pools and zero-knowledge proofs to let you deposit from any chain and withdraw to any chain while maintaining privacy. #### Is this a mixer? Shinobi Cash provides mixer-like privacy outcomes, but uses a different cryptographic model — one that preserves ownership proofs and enables compliance without surveillance. #### Is it safe to use? :::warning[Testnet Only] Shinobi Cash is currently on testnet and has NOT been audited. Use testnet ETH only. Do not deposit real funds. ::: #### What chains are supported? Currently on testnet: * **Arbitrum Sepolia** — Pool chain (where the privacy pool lives) * **Base Sepolia** — Origin chain (deposit/withdraw) More chains planned for mainnet. ### Privacy #### How private are my transactions? When you withdraw: * **Hidden**: Which deposit you're spending, your deposit history, your identity * **Revealed**: That you have a valid deposit, the withdrawal amount, the recipient address #### Can my deposits be linked to my withdrawals? Not by default. The zero-knowledge proof verifies you own a valid deposit without revealing which one. However: * Withdrawing immediately after depositing reduces anonymity * Withdrawing the exact same amount you deposited can be correlated * Using the same recipient address multiple times creates links #### What's an anonymity set? The anonymity set is all the deposits your withdrawal could be from. Larger is better. Shinobi Cash's crosschain approach creates a larger anonymity set than per-chain solutions. ### Compliance #### How does compliance work? Association Set Providers (ASPs) review deposits and approve compliant ones. Your withdrawal proof must show membership in both the deposit tree AND the ASP tree. #### What if my deposit is rejected? You can "ragequit" — withdraw by revealing you were the depositor. This recovers your funds but removes privacy. #### Do I need to KYC? No. Compliance is enforced at the protocol level via ASPs. You prove membership in a compliant set without revealing your identity. ### Technical #### Why is proof generation slow? Groth16 SNARK proofs are computationally intensive. The 5-15 second generation time is normal. Keep your browser tab active during generation. #### Do I need ETH in my wallet for gas? No. Withdrawals are relayed via standard ERC-4337 bundlers. A paymaster sponsors the gas upfront, and the cost is deducted from your withdrawal amount (relay fee). No custom relayer infrastructure required. #### Can I spend multiple notes at once? Yes. Withdraw2 lets you spend 2 notes in a single transaction. This is useful for consolidating small notes or making larger withdrawals from multiple deposits. #### What happens if a crosschain transaction fails? If a solver doesn't fill your intent before the deadline: * Your escrowed funds are returned to the pool as a refund commitment * You can withdraw the refund like any other deposit ### Fees #### What are the fees? :::info[Testnet] All fees are configurable and may change for mainnet. ::: **Deposits:** * Compliance fee (goes to protocol) * Solver fee (crosschain only) **Withdrawals:** * Relay fee (covers gas) * Solver fee (crosschain only) #### Why are fees high? Fees cover: * Gas costs (sponsored by paymasters) * Solver incentives (for crosschain settlement) * Protocol sustainability Fees may decrease as the protocol scales. #### Why are crosschain operations slow? Solver availability on testnet is limited. Crosschain deposits and withdrawals depend on solvers to fill intents. On mainnet, more solvers will provide faster settlement. ### Troubleshooting #### My deposit isn't showing up 1. Wait for transaction confirmation (\~1-2 blocks) 2. Wait for indexer sync (\~30 seconds) 3. For crosschain, wait for solver fill (\~1-5 minutes) 4. Try refreshing the page #### Withdrawal failed Common causes: * Note already spent (check another session didn't use it) * ASP approval pending (wait a bit longer) * Proof generation interrupted (try again, keep tab active) #### Transaction stuck For crosschain transactions, solvers usually fill within minutes. If expired: * Funds return as a refund commitment * Refund appears in your notes * Withdraw the refund normally ### More Questions? * **[Telegram](https://t.me/+tRxvbyeFuDNmMzUx)** — Join the community * **[GitHub](https://github.com/shinobi-cash)** — Report issues ## @shinobi-cash/constants :::info[Coming Soon] Documentation under development. API not yet stable. ::: ### Overview Contract addresses, ABIs, and chain configurations. ### Source Code [GitHub](https://github.com/shinobi-cash/shinobi.cash-website/tree/main/packages/constants) ## @shinobi-cash/core :::info[Coming Soon] Documentation under development. API not yet stable. ::: ### Overview Core cryptographic primitives and proof generation for Shinobi Cash. ### Source Code [GitHub](https://github.com/shinobi-cash/shinobi.cash-website/tree/main/packages/core) ## @shinobi-cash/data :::info[Coming Soon] Documentation under development. API not yet stable. ::: ### Overview Indexer client and query utilities. ### Source Code [GitHub](https://github.com/shinobi-cash/shinobi.cash-website/tree/main/packages/data) ## SDK :::info[Coming Soon] SDK documentation is under development. The API is not yet stable. ::: ### Packages | Package | Purpose | | ------------------------- | ------------------------------------------ | | `@shinobi-cash/core` | Cryptographic primitives, proof generation | | `@shinobi-cash/constants` | Contract addresses, ABIs, chain configs | | `@shinobi-cash/data` | Indexer client, queries | ### Status The SDK is in early development. APIs may change significantly before mainnet. ### Source Code * [GitHub](https://github.com/shinobi-cash/shinobi.cash-website/tree/main/packages) ## Depositing How to deposit into Shinobi Cash. ### Overview Depositing adds your funds to the privacy pool, creating a commitment that only you can later withdraw. *** ### Same-Chain Deposit When depositing on the pool chain: 1. **Navigate to Deposit** — Select the Deposit tab 2. **Enter Amount** — Enter the amount you want to deposit 3. **Review Fees** — Vetting fee applies (for compliance) 4. **Confirm** — Sign the transaction in your wallet Your deposit is added directly to the pool. *** ### Crosschain Deposit When depositing from an origin chain: 1. **Select Source Chain** — Choose where your funds are 2. **Enter Amount** — Enter the amount you want to deposit 3. **Review Fees**: * Vetting fee (compliance) * Solver fee (crosschain) * Network gas 4. **Confirm** — Sign the transaction A solver will detect your intent and deliver the deposit to the pool chain. *** ### Deposit States | Status | Meaning | | -------------- | ---------------------------------------- | | **Preparing** | Generating commitment and estimating gas | | **Submitting** | Awaiting wallet signature | | **Confirming** | Waiting for block confirmation | | **Confirmed** | On-chain; notes will sync shortly | For crosschain deposits, there's an additional wait for the solver to fill the intent. *** ### After Depositing Once confirmed, your deposit enters **pending** status while the ASP reviews it for compliance. When approved: * The deposit becomes **spendable** * You can withdraw privately *** ### Tips :::tip[Privacy Best Practice] Wait for more deposits after yours before withdrawing. A larger anonymity set means stronger privacy. ::: *** ### Troubleshooting #### Deposit stuck in pending * **Crosschain**: Wait for solver — usually fills within minutes * **ASP pending**: Testnet ASP auto-approves; should resolve quickly #### Transaction failed * Check you have enough funds for gas + deposit amount * Ensure you're on the correct network *** ### Ragequit If your deposit is stuck in pending and you need your funds back: * You can **ragequit** to recover funds to the original depositor address * Privacy is lost for that deposit This ensures you're never trapped waiting for approval. *** ### Learn More * **[Withdrawing](/guides/withdraw)** — How to withdraw privately * **[Privacy Pools](/concepts/privacy-pools)** — Understand the technology * **[Compliance](/concepts/compliance)** — How ASP approval works ## Withdrawing How to withdraw privately from Shinobi Cash. ### Overview Withdrawing uses a zero-knowledge proof to verify you own a deposit without revealing which one. The recipient can be any address on any supported chain. *** ### Withdrawal Steps 1. **Navigate to Withdraw** — Select the Withdraw tab 2. **Select Notes** — Choose one or two notes to withdraw from 3. **Enter Amount** — Up to the total balance of selected notes 4. **Enter Recipient** — Any valid address 5. **Select Destination Chain** — Where funds should arrive 6. **Review Fees** — Relay fee + solver fee (if crosschain) 7. **Confirm** — Proof generates in your browser, then submits *** ### Note Selection You can select **up to 2 notes** for a single withdrawal: | Mode | Description | | ------------------- | ------------------------------------- | | **Single note** | Withdraw from one note | | **Merge (2 notes)** | Combine two notes into one withdrawal | Merging is useful when you have multiple small notes and want to make a larger withdrawal. When you select 2 notes, the UI shows a "Merge" indicator. *** ### Proof Generation When you confirm a withdrawal, your browser generates a zero-knowledge proof. This takes approximately **5-15 seconds**. Keep the browser tab active during this time. The proof verifies: * You know the secret for a valid commitment * The commitment is in the pool and approved by an ASP * The nullifier hasn't been spent *** ### No Wallet Gas Required Shinobi Cash uses **ERC-4337 Account Abstraction** for withdrawals: * You don't need gas in your wallet * A paymaster sponsors the transaction * Gas cost is deducted from your withdrawal (relay fee) This means you can withdraw to a fresh address without funding it first. *** ### Same-Chain Withdrawal When withdrawing on the pool chain: 1. Proof validates in the pool contract 2. Funds transfer directly to recipient 3. Paymaster sponsors gas **Fees**: Relay fee only *** ### Crosschain Withdrawal When withdrawing to an origin chain: 1. Proof validates on pool chain 2. Intent created with escrowed funds 3. Solver fills on destination chain 4. Recipient receives funds **Fees**: Relay fee + solver fee *** ### Change Notes A **change note** is always created with your remaining balance: | | Amount | | -------------- | ---------------- | | Selected notes | 1.0 | | Withdrawal | 0.3 | | Change note | 0.7 (minus fees) | If you withdraw the full amount, the change note has zero balance. *** ### Withdrawal States | Status | Meaning | | -------------- | ---------------------------------- | | **Preparing** | Generating zero-knowledge proof | | **Submitting** | Transaction being sent via bundler | | **Confirming** | Waiting for block confirmation | | **Confirmed** | Complete; notes will sync shortly | For crosschain withdrawals, there's an additional wait for the solver to fill. *** ### Fees | Fee | When | Purpose | | -------------- | --------------- | -------------------- | | **Relay Fee** | Always | Covers gas (dynamic) | | **Solver Fee** | Crosschain only | Compensates solver | *** ### Tips :::tip[Privacy Best Practice] Withdraw to a fresh address that has no connection to your depositing address. ::: :::tip[Partial Withdrawals] You can make multiple partial withdrawals. Each creates a change note with the remaining balance. ::: *** ### Troubleshooting #### Proof generation is slow * Keep the browser tab active and focused * Close other resource-heavy tabs * Normal time: 5-15 seconds #### Transaction failed * Check the note is still available (not spent elsewhere) * Verify recipient address is valid * Ensure ASP approval is complete #### Crosschain withdrawal stuck * Solvers usually fill within minutes * If expired, funds return as a refund commitment * Refund can be withdrawn normally *** ### Important :::warning[Recipient Address] Always double-check the recipient address. Withdrawals to wrong addresses **cannot be recovered**. ::: *** ### Learn More * **[Privacy Pools](/concepts/privacy-pools)** — Understand the cryptography * **[Crosschain Architecture](/concepts/cross-chain)** — How crosschain works * **[FAQ](/faq)** — Common questions ## Entrypoints Entrypoints are the **only user-facing contracts** in Shinobi Cash.\ They coordinate proof verification, intent creation, and crosschain fund movement by interacting with pools, settlers, and oracles. *** ### Design Principle Shinobi separates entrypoints by **authority domain**. | Contract | Chain | Responsibility | | ------------------------------------ | -------------------------- | ------------------------------------------------- | | `ShinobiCashEntrypoint` | Pool chain (Arbitrum) | Proof-verified withdrawals and pool state updates | | `ShinobiCrosschainDepositEntrypoint` | Origin chains (Base, etc.) | User-originated crosschain deposits | Users always interact with the entrypoint on the chain where they currently hold funds. Entrypoints **do not custody funds** — funds flow through to settlers in the same transaction. *** ### ShinobiCashEntrypoint (Pool Chain) The canonical orchestrator on the pool chain.\ Extends the base `Entrypoint` from `privacy-pools-core`. #### Responsibilities * **Crosschain withdrawals** * Verifies ZK proof via the pool * Creates OIF withdrawal intent * Escrows funds for solver settlement * **Crosschain deposits** * Accepts verified deposit fills from `ShinobiDepositOutputSettler` * Inserts commitments into the pool * **Refund handling** * Accepts expired withdrawal intents from `ShinobiInputSettler` * Inserts refund commitments into the pool * **Same-chain withdrawals** * `withdraw2`: spends two notes on the pool chain * `crosschainWithdraw2`: spends two notes and exits crosschain #### Access Control * Withdrawal functions are **permissionless** (valid proof required) * Crosschain deposit handler callable **only** by `ShinobiDepositOutputSettler` * Refund handler callable **only** by `ShinobiInputSettler` *** ### ShinobiCrosschainDepositEntrypoint (Origin Chains) Entrypoint deployed on non-pool chains where users hold assets. #### Responsibilities * **Crosschain deposits** * Accepts funds and a precommitment * Creates an OIF deposit intent * Escrows funds in `ShinobiInputSettler` * Submits intent proof to the pool chain via Hyperlane * **Refund initiation** * Proxies refund requests for expired deposit intents * Refund execution remains permissionless via `InputSettler` #### Deposit Flow 1. User calls `deposit()` with funds and a precommitment 2. Entrypoint creates an OIF intent and escrows funds in `InputSettler` 3. Intent proof is relayed to the pool chain 4. Solver fills the intent via `ShinobiDepositOutputSettler` 5. Solver claims escrowed funds after proving the fill *** ### Precommitments Both entrypoints require a **precommitment** derived from the user’s secret. Precommitments: * are marked as used on first submission * cannot be reused on the same chain * prevent replay and duplicate intent creation Precommitments do **not** reveal note secrets or link deposits and withdrawals. *** ### Security Notes * Entrypoints do not custody funds (funds flow through to settlers) * All withdrawals require valid ZK proofs * Crosschain actions are finalized only via settler + oracle validation * Entrypoints are **not trusted** for correctness beyond enforcing invariants *** ### Source Code * [ShinobiCashEntrypoint](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/core/ShinobiCashEntrypoint.sol) * [ShinobiCrosschainDepositEntrypoint](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/core/ShinobiCrosschainDepositEntrypoint.sol) *** ### Related * **[Privacy Pool](/contracts/pool)** — Proof validation and commitment management * **[Shinobi x OIF](/contracts/oif)** — Crosschain settlement logic * **[Crosschain Architecture](/concepts/cross-chain)** — End-to-end system flow ## Smart Contracts Overview of the Shinobi Cash smart contract architecture. *** ### High-Level Architecture Shinobi deploys contracts across **two chain types**, with a single canonical privacy pool. #### Pool Chain (Arbitrum) | Contract | Role | | ----------------------------- | ------------------------------------------------------- | | `ShinobiCashEntrypoint` | Orchestrates withdrawals, receives crosschain deposits | | `ShinobiCashPool` | Privacy pool — commitments, nullifiers, ZK verification | | `ShinobiInputSettler` | Escrow and refunds for withdrawal intents | | `ShinobiDepositOutputSettler` | Fills crosschain deposit intents | | `Paymasters` | ERC-4337 gas sponsorship | #### Origin Chains (Base, etc.) | Contract | Role | | ------------------------------------ | -------------------------------------- | | `ShinobiCrosschainDepositEntrypoint` | User deposit interface | | `ShinobiInputSettler` | Escrow and refunds for deposit intents | | `ShinobiWithdrawalOutputSettler` | Fills crosschain withdrawal intents | The **pool chain** is the source of truth for privacy state. **Origin chains** provide deposit interfaces and receive withdrawal execution. All crosschain movement is mediated via **OIF settlers and oracles**. *** ### Core Contract Groups #### Entrypoints User-facing contracts that orchestrate deposits and withdrawals. * **`ShinobiCashEntrypoint`** (pool chain)\ Proof-verified withdrawals, pool updates, refund commitments * **`ShinobiCrosschainDepositEntrypoint`** (origin chains)\ User interface for crosschain deposits *** #### Privacy Pool Canonical privacy state. * Commitment insertion (deposits) * Nullifier spending (withdrawals) * Multi-note spending (`withdraw2`) *** #### Shinobi × OIF (Settlers) Crosschain escrow, fills, and refunds using the Open Intent Framework. * **`ShinobiInputSettler`** — escrow and refunds on origin chains * **`ShinobiDepositOutputSettler`** — deposit fills with mandatory intent validation * **`ShinobiWithdrawalOutputSettler`** — optimistic withdrawal fills *** #### Paymasters ERC-4337 paymasters for gasless withdrawals. * Replace relayers and pre-funded wallets * Enforce fees on-chain * Use standard AA infrastructure *** ### Next * **[Entrypoints](/contracts/entrypoint)** — Authority and orchestration * **[Privacy Pool](/contracts/pool)** — ZK validation and state * **[Shinobi x OIF](/contracts/oif)** — Crosschain settlement * **[Paymasters](/contracts/paymasters)** — Gas sponsorship ## Shinobi x OIF Shinobi Cash extends the **Open Intent Framework (OIF)** with specialized settlers to support **privacy-preserving crosschain deposits and withdrawals**. The core extension addresses a fundamental mismatch between **optimistic settlement** and **privacy pools**. *** ### Design Principle Standard OIF assumes **optimistic settlement**: * solvers fill intents * later prove the fill to claim escrowed funds This model works for swaps, where economic incentives align. **Privacy pools break this assumption.** When deposits are created via intents, the **depositor address determines compliance status**.\ If a solver can fill an intent *without proving the original deposit existed*, the system becomes vulnerable to laundering. *** ### Why Optimistic Settlement Fails for Deposits In a privacy context, the attacker can be the **user and solver**. Without deposit intent validation: 1. Attacker signs a deposit intent with a clean address B 2. Attacker (as solver) fills it using illicit funds from address A 3. Deposit is attributed to B → passes ASP compliance 4. Attacker withdraws "clean" funds using a ZK proof Standard OIF relies on solver profit motive for security — but laundering attacks are not economically disincentivized. *** ### Shinobi’s Extension: Intent-Proven Deposits Shinobi requires **intent proof validation for deposits**. Before a deposit intent can be filled on the pool chain, the destination must verify that: * the intent was created on the origin chain * funds were actually escrowed * the depositor address matches the escrow provider This is enforced via an **intentOracle**. > **Invariant:**\ > *The address receiving compliance status must be the address that provided the funds.* *** ### Settler Architecture Shinobi uses three settler contracts: | Contract | Chain | Role | | -------------------------------- | ----------- | ----------------------------------------- | | `ShinobiInputSettler` | Origin | Escrows funds, handles claims and refunds | | `ShinobiDepositOutputSettler` | Pool | Fills deposit intents (**intent-proven**) | | `ShinobiWithdrawalOutputSettler` | Destination | Fills withdrawal intents (optimistic) | *** ### ShinobiInputSettler (Origin) Manages the origin side of crosschain operations: * escrows funds * releases funds to solvers after fill proof * refunds expired intents (permissionless) **Lifecycle:** ``` None → Deposited → Claimed ↓ Refunded ``` Refunds differ by flow: * **Deposits** → direct ETH refund * **Withdrawals** → refund commitment created in the pool *** ### ShinobiDepositOutputSettler (Pool Chain) Handles deposit fills with **mandatory intent validation**. Before accepting a fill, it verifies via `intentOracle` that: * the intent exists on the origin chain * escrowed funds are present * chain configuration matches If intent proof is missing or invalid, the fill is rejected. :::warning[Critical Security] This validation is the key difference from standard OIF.\ Without it, privacy pools are vulnerable to free laundering. ::: *** ### ShinobiWithdrawalOutputSettler (Destination) Handles withdrawal fills using **optimistic settlement**. No intent proof validation is required because: * the ZK proof was verified on the pool chain * the entrypoint only creates intents after proof verification * ownership and amount are cryptographically enforced Solvers fill the withdrawal, then prove the fill via `fillOracle` to claim escrowed funds. *** ### Oracle System | Oracle | Direction | Purpose | | -------------- | -------------------- | ------------------------------------- | | `fillOracle` | Destination → Origin | Proves fills occurred (claims) | | `intentOracle` | Origin → Destination | Proves deposit intents are legitimate | *** ### Security Summary | Aspect | Deposits | Withdrawals | | --------------------- | --------------------------- | ------------------------------- | | Optimistic settlement | ❌ | ✅ | | Intent proof required | ✅ | ❌ | | Why | Prevents depositor spoofing | ZK proof already validates user | | Fill validation | fillOracle | fillOracle | | Refund | ETH to user | Commitment in pool | *** ### Source Code * [ShinobiInputSettler](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/oif/ShinobiInputSettler.sol) * [ShinobiDepositOutputSettler](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/oif/ShinobiDepositOutputSettler.sol) * [ShinobiWithdrawalOutputSettler](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/oif/ShinobiWithdrawalOutputSettler.sol) *** ### Related * **[Entrypoints](/contracts/entrypoint)** — Creates intents * **[Crosschain Architecture](/concepts/cross-chain)** — End-to-end flow ## Paymasters Shinobi Cash uses **ERC-4337 paymasters** to enable **gasless, private withdrawals**. Paymasters sponsor gas **on-chain** and are repaid from the withdrawn amount — allowing withdrawals to target fresh, unfunded addresses without relying on third-party relayers. In privacy protocols, **gas handling is part of the threat model**, not just a UX concern. *** ### Design Principle When withdrawing from a privacy protocol, users realistically have two options: 1. **Use a relayer** — Preserves UX but introduces trust and off-chain coordination 2. **Pre-fund a fresh address** — Avoids relayers but adds friction and linkage risks Shinobi uses **ERC-4337 paymasters** to replace both with a single, on-chain mechanism that preserves privacy guarantees without protocol-specific infrastructure. *** ### Why ERC-4337 Paymasters Relayer-based designs rely on centralized infrastructure, off-chain fee negotiation, and additional trust assumptions. ERC-4337 paymasters allow Shinobi to: * **Use standard AA infrastructure** — Compatible with existing bundlers (Pimlico, Alchemy, etc.) * **Keep fee logic on-chain** — Gas sponsorship and repayment enforced by contracts * **Minimize trusted surface** — No new trust assumptions beyond the ERC-4337 model This keeps the withdrawal path **deterministic, auditable, and composable**. *** ### Paymaster Selection | Scenario | Paymaster | | -------------------- | -------------------------------------------- | | Same-chain, 1 note | `ShinobiNativeWithdrawalPaymaster` | | Cross-chain, 1 note | `ShinobiNativeCrosschainWithdrawalPaymaster` | | Same-chain, 2 notes | `ShinobiNativeWithdraw2Paymaster` | | Cross-chain, 2 notes | `ShinobiNativeCrosschainWithdraw2Paymaster` | The application selects the appropriate paymaster based on note count and destination chain. *** ### Security * Paymasters **cannot steal funds** * Gas sponsorship is bounded and deterministic * Failed execution results in a revert * Bundlers and UI are explicitly untrusted *** ### Source Code * [ShinobiNativeWithdrawalPaymaster](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/paymaster/ShinobiNativeWithdrawalPaymaster.sol) * [ShinobiNativeCrosschainWithdrawalPaymaster](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/paymaster/ShinobiNativeCrosschainWithdrawalPaymaster.sol) * [ShinobiNativeWithdraw2Paymaster](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/paymaster/ShinobiNativeWithdraw2Paymaster.sol) * [ShinobiNativeCrosschainWithdraw2Paymaster](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/paymaster/ShinobiNativeCrosschainWithdraw2Paymaster.sol) *** ### Related * **[Entrypoints](/contracts/entrypoint)** — Withdrawal orchestration * **[Privacy Pool](/contracts/pool)** — Proof validation ## Privacy Pool The privacy pool is the core contract that holds deposits, validates ZK proofs, and processes withdrawals. *** ### Design Principle Shinobi extends the base `PrivacyPool` from [privacy-pools-core](https://github.com/0xbow-io/privacy-pools-core) with: * **Crosschain withdrawals** with refund protection * **Multi-note spending** (Withdraw2) for consolidating balances * **Refund handling** for failed crosschain intents The pool maintains a single Merkle tree of commitments, enabling a unified anonymity set across all supported chains. *** ### Core Operations #### Deposits Commitments are inserted into the Merkle tree. Each deposit creates a leaf that only the depositor can later spend (using knowledge of the secret). #### Withdrawals Users generate a ZK proof demonstrating: * Ownership of a valid commitment (without revealing which one) * Membership in the ASP-approved set (compliance) * The nullifier hasn't been spent The pool verifies the proof, marks the nullifier as spent, and releases funds. *** ### Withdrawal Types The pool supports four withdrawal modes: * **Single note** — Withdraw from one note on the same chain * **Single note crosschain** — Withdraw from one note to a different chain * **Two notes** — Spend 2 notes in one transaction (useful for consolidating small balances) * **Two notes crosschain** — Spend 2 notes with delivery to a different chain Crosschain withdrawals include a **refund commitment**. If the solver fails to fill the intent, the refund is inserted into the pool and the user can withdraw normally. *** ### Proof Validation Each withdrawal type has a dedicated verifier contract. The pool validates: 1. **State root** — Must be in recent history (allows concurrent proof generation) 2. **ASP root** — Must be the latest (ensures compliance is current) 3. **Context** — Binds the proof to specific withdrawal parameters (prevents replay) 4. **Nullifier** — Must not be already spent (prevents double-spending) *** ### Security Model | Property | Enforcement | | ------------------------- | ---------------------- | | Double-spend prevention | Nullifier registry | | Proof replay prevention | Context binding | | Compliance enforcement | ASP root validation | | Concurrent proof support | Root history (last 30) | | Refund-only by entrypoint | Access control | *** ### Source Code * [ShinobiCashPool](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/core/ShinobiCashPool.sol) * [ShinobiCashPoolSimple](https://github.com/shinobi-cash/shinobi.cash-contracts/blob/main/src/core/ShinobiCashPoolSimple.sol) (native ETH implementation) *** ### Related * **[Entrypoints](/contracts/entrypoint)** — Orchestrate crosschain operations * **[Privacy Pools](/concepts/privacy-pools)** — Cryptographic foundations * **[Shinobi x OIF](/contracts/oif)** — Crosschain settlement ## Compliance :::info[TL;DR] Shinobi Cash uses **Association Set Providers (ASPs)** to approve compliant deposits. Withdrawals prove membership in an approved set **without revealing which deposit was used**. Privacy is preserved; compliance is verifiable. ::: *** ### The Problem Privacy systems face a structural tradeoff: * Full privacy makes it difficult to demonstrate that funds are clean * Full transparency removes privacy entirely Shinobi Cash adopts the **Privacy Pools** approach: compliance is enforced at the **deposit level**, while privacy is preserved at **withdrawal time**. *** ### Association Set Providers (ASPs) An **Association Set Provider (ASP)** is an entity that reviews deposits and decides whether they belong to a compliant set. ASPs do **not** control withdrawals and do **not** learn which deposit is later withdrawn. *** ### How ASPs Work 1. A user makes a deposit → a commitment is added to the pool's state tree (status: pending) 2. An ASP reviews the deposit source off-chain 3. If approved, the commitment's label is added to the ASP's association set 4. To withdraw, the user generates a zero-knowledge proof The proof verifies: * The deposit exists in the pool state * The deposit exists in the ASP's approved set * The user knows the deposit secret It does **not** reveal: * Which deposit was used * When the deposit occurred * The depositor's address or identity This allows compliance checks **without transaction-level surveillance**. *** ### Approval States | State | Meaning | Withdrawal | | ------------ | --------------------------- | -------------------------------- | | **Pending** | Awaiting ASP decision | Not allowed (ragequit available) | | **Approved** | Commitment added to ASP set | Private withdrawal allowed | *** ### Ragequit (Fund Recovery) While a deposit is pending, the user can **ragequit**: * Funds are returned to the original depositor address * Privacy is lost for that deposit This ensures users are never trapped waiting for approval. *** ### Learn More * **[Privacy Pools Paper](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364)** — Research foundation * **[Privacy Pools](/concepts/privacy-pools)** — Cryptographic model * **[Smart Contracts](/contracts/)** — Implementation details ## Crosschain Architecture :::info[TL;DR] Shinobi Cash uses **one privacy pool on a single chain**. Deposits and withdrawals from other chains are handled via **intents** fulfilled by **solvers**. Funds are always escrowed or recoverable — solvers can delay, but **cannot steal**. ::: *** ### The Problem Most privacy protocols deploy a separate pool on each chain. This fragments the anonymity set: * fewer users per pool * weaker privacy guarantees * worse UX across chains *** ### The Solution Shinobi Cash maintains **one canonical privacy pool** on a single chain, while allowing users to deposit from and withdraw to many chains. **Result:**\ One pool. Every chain. Stronger anonymity. *** ### Key Concepts | Term | Meaning | | ---------------- | ----------------------------------------------------- | | **Pool chain** | The chain where the privacy pool lives | | **Origin chain** | Any chain users deposit from or withdraw to | | **Intent** | A request to move funds across chains | | **Solver** | An off-chain actor that fulfills intents for a fee | | **Escrow** | Funds locked until the intent is completed or expires | *** ### How Solvers Work Solvers are permissionless off-chain actors. They: 1. Monitor chains for new intents 2. Execute the requested action on the destination chain 3. Prove execution via an oracle 4. Receive escrowed funds as payment A solver may choose **not** to act, but **cannot steal funds**. *** ### Crosschain Deposits (High Level) 1. User deposits funds on an origin chain 2. Funds are escrowed and an intent is created 3. A solver fulfills the intent on the pool chain 4. A deposit commitment is added to the privacy pool 5. Solver proves completion and receives escrowed funds Deposits are only accepted if the intent corresponds to a **real escrowed deposit**. *** ### Crosschain Withdrawals (High Level) 1. User generates a zero-knowledge proof on the pool chain 2. A withdrawal intent is created and funds are escrowed 3. A solver executes the withdrawal on the destination chain 4. User receives funds 5. Solver proves completion and receives escrowed funds Withdrawals are privacy-preserving and unlinkable to deposits. *** ### Refunds and Failure Handling If an intent is **not filled** before expiry: | Flow | What Happens | | -------------- | -------------------------------------------- | | **Deposit** | Funds are returned directly to the depositor | | **Withdrawal** | A refund commitment is created in the pool | This ensures funds are **never lost**, even if no solver participates. *** ### What This Design Guarantees * One shared anonymity set across chains * No reliance on trusted relayers * No loss of funds due to solver failure * Privacy preserved across chains *** ### Learn More * **[Shinobi x OIF](/contracts/oif)** — Settlement mechanics * **[Compliance](/concepts/compliance)** — ASP-based compliance * **[Privacy Pools](/concepts/privacy-pools)** — Cryptographic foundations ## Privacy Pools :::info[TL;DR] Deposits create **commitments** in a shared Merkle tree. Withdrawals reveal **nullifiers** that prove ownership without revealing which deposit was used. Zero-knowledge proofs verify everything on-chain without leaking information. ::: *** ### The Core Idea Privacy Pools break the public link between deposits and withdrawals. Users deposit funds into a shared pool and later withdraw using **zero-knowledge proofs** that demonstrate: * they own a valid deposit, and * the deposit has not been spent before without revealing **which deposit** it was. *** ### Key Concepts | Term | Meaning | | ------------------------ | --------------------------------------------------------------------- | | **Commitment** | A cryptographic representation of a deposit | | **Nullifier** | A value revealed at withdrawal to prevent double-spending | | **Merkle Tree** | A structure that allows proving membership without revealing position | | **Zero-Knowledge Proof** | A proof that verifies correctness without revealing private data | *** ### A Simple Example Alice deposits 1 ETH: * A commitment is added to the pool * Alice stores a secret locally Later, Alice withdraws 0.3 ETH: * She generates a proof: "I own some deposit in the pool" * She reveals a nullifier (marking that deposit as spent) * She receives 0.3 ETH * A new commitment (0.7 ETH) is created as change On-chain observers see: * A deposit occurred * A withdrawal occurred * A nullifier was spent They **cannot link** the withdrawal to the original deposit. *** ### Commitments When a user deposits, a **commitment** is created and added to a Merkle tree. * Commitments are public * The underlying secret is known only to the depositor * Commitments cannot be reversed or linked to a future withdrawal *** ### Nullifiers When withdrawing, the user reveals a **nullifier** derived from their secret. * Each deposit has exactly one nullifier * Once revealed, it is marked as spent * This prevents double-spending without revealing deposit identity *** ### Zero-Knowledge Proofs Each withdrawal includes a zero-knowledge proof that verifies: 1. The user owns a valid commitment in the pool 2. The nullifier is correctly derived and unused 3. The deposit belongs to an approved compliance set (via ASP) The proof reveals **nothing** about: * Which deposit was used * When it was created * Who created it *** ### Merkle Trees Shinobi Cash maintains two Merkle trees: | Tree | Purpose | | ------------------- | ----------------------------------------------------------------- | | **Pool State Tree** | Contains all deposit commitments (the full anonymity set) | | **ASP Tree** | Contains only commitments approved by an Association Set Provider | Both trees are referenced inside the withdrawal proof. *** ### Withdrawal Variants | Type | Description | | -------------------------- | ------------------------------------------- | | **Single note** | Same-chain withdrawal from one deposit | | **Two notes** | Spend two deposits in one withdrawal | | **Crosschain** | Withdrawal to another chain via a solver | | **Crosschain (two notes)** | Two-deposit withdrawal delivered crosschain | All withdrawals: * Are unlinkable to deposits * Always create a change commitment with the remaining amount * Never expose deposit identity *** ### What's Hidden vs Revealed | Hidden | Revealed | | ----------------------- | --------------------------- | | Which deposit was spent | That a valid deposit exists | | Deposit history | The nullifier (once spent) | | Link to identity | Withdrawal amount | | | Recipient address | Privacy depends on using the system correctly (e.g., avoiding timing or amount correlation). *** ### Learn More * **[Crosschain Architecture](/concepts/cross-chain)** — How privacy works across chains * **[Compliance](/concepts/compliance)** — Association Set Providers * **[Smart Contracts](/contracts/)** — Implementation details