> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloak.ag/llms.txt
> Use this file to discover all available pages before exploring further.

# Shield Pool Program

> Program behavior that SDK and app integrators need to know

## Program identifier

* `zh1eLd6rSphLejbFfJEneUwzHRfMKxgzrgkfwA6qRkW`

## Instruction surface

* `0`: `Transact` (deposit, withdraw, shielded transfer)
* `1`: `TransactSwap` (swap flow entrypoint)
* `2`: `Initialize` (mint-scoped pool bootstrap)
* `3`: `PrepareSwapSol`
* `4`: `ExecuteSwap`
* `5`: `CloseSwapState`
* `6`: `CollectTreasury`

SDK consumers typically interact through `Transact` and `TransactSwap`.

## Public input layout

`Transact` and `TransactSwap` both use a `264`-byte public input blob:

* `root[32]`
* `publicAmount[8]` (`i64`, LE)
* `extDataHash[32]`
* `mintAddress[32]`
* `inputNullifiers[64]` (2 x 32)
* `outputCommitments[64]` (2 x 32)
* `chainNoteHash[32]`

This matches the transaction circuit constraints.

## Fees and amount semantics

* `FIXED_FEE_LAMPORTS = 5_000_000` (0.005 SOL floor)
* Variable fee: `amount * 3 / 1000` (0.3%)
* `MIN_DEPOSIT_LAMPORTS = 10_000_000` (0.01 SOL)

SOL withdrawal and swap math:

* `gross = abs(publicAmount)`
* `fee = 5_000_000 + gross * 3 / 1000`
* `net = gross - fee`

The program enforces sufficient withdrawal amount so `net > 0`.

## Merkle tree and nullifiers

* Tree height: `32`
* Root history size: `100`
* Nullifier PDA seed model: `["nullifier", pool_pubkey, nullifier_hash]`

Mint-scoped PDAs:

* Pool: `["pool", mint]`
* Treasury: `["treasury", mint]`
* Merkle tree: `["merkle_tree", mint]`

## Execution model

### `Transact`

* Verifies 256-byte Groth16 proof against transaction verifier key.
* Validates root exists in root history ring.
* Creates nullifier PDAs for non-zero input nullifiers (double-spend protection).
* Appends non-zero output commitments to Merkle tree.
* Applies external transfer based on `publicAmount`:
  * positive: deposit from payer to pool
  * negative: withdrawal from pool to recipient + fee to treasury
  * zero: pure shield transfer (no external SOL movement)
* Deposit path can require risk-oracle quote accounts when configured.

### `TransactSwap`

* Runs the same proof/nullifier/commitment checks as `Transact`.
* Requires negative `publicAmount` (swap is a withdrawal path).
* Creates `SwapState` for the follow-up settlement path.

## Circuit assumptions the program relies on

* Transaction circuit is fixed to 2 inputs / 2 outputs.
* Tree depth is fixed to 32 levels.
* Circuit enforces value conservation: `sum(inputs) + publicAmount = sum(outputs)`.
* Circuit includes `chainNoteHash` binding constraints for chain-note integrity.

## Error mapping

For SDK-side mapping utilities, see `ShieldPoolErrors` in [Error Handling](/sdk/error-handling).

## Common failure modes

* `0x1001 RootNotFound`: proof used an old root no longer in ring history.
* `0x1020`/nullifier-already-used: input already spent (or reused test nullifier).
* Invalid instruction data: wrong public input length (must be 264 bytes).
