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

# Contract roles and bindings

See what each current Nullark contract does and which runtime values must match before a deposit or withdrawal is trusted.

One runtime supplies every address in the call path. Keep that object intact instead of selecting contracts one by one.

Use [Current runtime](/reference/current-runtime.md) for the exact pinned values.

## Contract responsibilities

| Role | Responsibility | Must match |
| --- | --- | --- |
| Pool | Holds ETH, inserts bundle commitments, tracks roots and nullifiers, applies fees, and pays withdrawals | Chain, deployment block, accounting, and verifier routes |
| Deposit verifier | Checks the six-input deposit relation | Key hash, bytecode hash, setup, and input order |
| Withdrawal verifier | Checks the nine-input selected-child withdrawal relation | Key hash, bytecode hash, setup, and input order |
| Deposit adapter | Binds the pool to the deposit verifier interface | Pool, verifier, and adapter bytecode |
| Withdrawal adapter | Binds the pool to the withdrawal verifier interface | Pool, verifier, and adapter bytecode |
| Poseidon2 and Poseidon6 | Provide the field hashes used by tree and bundle relations | Address, bytecode, and field semantics |
| Fee controller | Manages the active fee within the contract's hard maximum | Controller address and live fee state |

## Deposit path

```mermaid
flowchart TB
  subgraph Client["Trusted client"]
    PREP["Prepare bundle, recovery envelope, and proof"]
    WALLET["Wallet reviews the transaction"]
    PREP -->|exact unsigned request| WALLET
  end

  subgraph Chain["Pool checks"]
    POOL["Nullark pool"]
    CHECK{"Six inputs and proof valid?"}
    ACCEPT["Insert bundle commitment and accept new root"]
    REVERT["Revert with no state change"]
    POOL -->|verify deposit| CHECK
    CHECK -->|yes| ACCEPT
    CHECK -->|no| REVERT
  end

  WALLET -->|ETH and deposit calldata| POOL
```

The pool requires the transaction value to equal the proof-bound amount. It also binds the commitment, chain, pool, deposit context, and encrypted recovery payload hash.

## Withdrawal path

```mermaid
flowchart TB
  subgraph Client["Trusted client"]
    RESTORE["Restore bundle and select one child"]
    PROVE["Prove membership and ownership locally"]
    SUBMIT["Wallet reviews zero-value calldata"]
    RESTORE -->|private witness| PROVE
    PROVE -->|exact unsigned request| SUBMIT
  end

  subgraph Chain["Pool checks"]
    POOL["Nullark pool"]
    CHECK{"Root accepted, nullifier unused, fee and proof valid?"}
    ACCEPT["Record nullifier, accrue fee, send net ETH"]
    REVERT["Revert with no state change"]
    POOL -->|verify withdrawal| CHECK
    CHECK -->|yes| ACCEPT
    CHECK -->|no| REVERT
  end

  SUBMIT -->|zero-value withdrawal call| POOL
```

The proof binds the destination, gross amount, fee, chain, pool, proof context, and encrypted payload. An unspent sibling already belongs to the deposited bundle, so a withdrawal creates no new commitment.

## Code and accounting

Runtime validation combines addresses with expected code and verifier identities, then uses live reads for current fee state.

The pool's ETH and accounting must cover every allowed exit without counting accrued fees twice. UI balances and transaction receipts are views of that state, not alternate ledgers.
