# Deploying pools

Deploying a new TONado Cash pool means standing up a fresh `pool_native.tolk` or `pool_jetton.tolk` contract for a specific `(asset, denomination)` combination. The order matters; each step depends on the previous.

For mainnet, see the [Mainnet launch plan](/operations/mainnet-launch-plan.md); it gates deployment on an external audit and a multi-party trusted-setup ceremony. **Do not deploy on mainnet without completing both gates.**

## Order of operations

| Order | Step                                      | Command                                                          |
| ----- | ----------------------------------------- | ---------------------------------------------------------------- |
| 1     | Download phase-1 ptau                     | `pnpm circuits:ptau-setup`                                       |
| 2     | Compile circuit + dev zkey                | `pnpm circuits:compile`                                          |
| 3     | *(mainnet only)* Multi-party ceremony     | See [Trusted-setup ceremony](/operations/ceremony.md)            |
| 4     | Export Tolk verifier from final zkey      | `pnpm verifier:export`                                           |
| 5     | Precompute merkle-tree zeros table        | `pnpm --filter @tonado/contracts run precompute-zeros`           |
| 6     | Verify Poseidon parity (prover ↔ circuit) | `tsx apps/contracts/scripts/check-poseidon-parity.ts`            |
| 7     | Build Tolk contracts                      | `cd apps/contracts && acton build`                               |
| 8     | Run sandbox tests                         | `acton test`                                                     |
| 9     | Deploy each pool                          | `pnpm deploy:pool -- --network <net> --asset <a> --amount <n>`   |
| 10    | Verify each deployment                    | `pnpm deploy:verify -- --network <net> --asset <a> --amount <n>` |
| 11    | Commit updated `deployments.ts`           | `git commit packages/core/src/deployments.ts`                    |

Steps 1–8 are one-time per circuit version. Steps 9–11 are per pool.

## The deploy script

`apps/contracts/scripts/deploy-pool.ts` is invoked by `pnpm deploy:pool`. It reads:

| Env var              | Purpose                                                         |
| -------------------- | --------------------------------------------------------------- |
| `DEPLOYER_MNEMONIC`  | 24-word mnemonic of the wallet that signs the deploy.           |
| `TONCENTER_ENDPOINT` | Optional override; defaults to the network's standard endpoint. |
| `TONCENTER_API_KEY`  | Required for production-volume calls.                           |
| `TON_NETWORK`        | Overridden by `--network` flag.                                 |

And accepts:

* `--network testnet|mainnet`
* `--asset ton` for native, or `--asset jetton:<master-friendly-addr>` for a TEP-74 jetton pool.
* `--amount <human-readable-amount>` (e.g. `1`, `10`, `100`).
* `--jetton-symbol <SYM>` and `--jetton-decimals <N>` for jetton pools, so the registry has display metadata.
* `--burn-owner` (or `TONADO_BURN_OWNER=1`): deploy with `owner = address_none()` so the admin handlers are permanently uncallable. **Strongly recommended for mainnet.** See [Threat model: owner / governance model](/protocol-reference/threat-model.md). **Note:** incompatible with jetton deploys, which require the owner to send `AdminBindJettonWallet` before sealing.

### What the deploy script does

1. Loads the wallet from the mnemonic.
2. Reads the compiled BoC from `apps/contracts/build/PoolNative.json` (or `PoolJetton.json`).
3. Builds the initial data cell:
   * `paused = false`
   * `owner = deployer wallet` (or `address_none()` if `--burn-owner`)
   * `currentRoot = empty-tree root` (the Poseidon-of-zeros chain up to height 20)
   * `nextIndex = 0`
   * `nullifiersCount = 0`
   * dicts: all null
4. Computes the resulting state-init address.
5. Sends a single deploy tx with 0.5 TON attached.
6. Polls until the contract is `active`.
7. Patches `packages/core/src/deployments.ts` with the new address.

## Verifying a deployment

```bash
pnpm deploy:verify -- --network testnet --asset ton --amount 1
```

This:

* Confirms `contract.state === "active"`.
* Calls `get_denomination` and asserts it matches the recorded value.
* Calls `get_next_index` and asserts it's `0` (fresh pool) or matches the indexer.
* Calls `get_current_root` and prints it for visual cross-check.

If anything mismatches, the script exits non-zero so CI can gate on it.

## Jetton pools: two-pass deploy

A jetton pool needs to know its **own** jetton wallet address before it can validate `transfer_notification`s. But the wallet address depends on `jetton_master.get_wallet_address(<pool-address>)`, which depends on the pool's address, which depends on its state-init. Circular.

The solution implemented in [`apps/contracts/scripts/deploy-pool.ts`](https://github.com/tonadocash/monorepo/blob/main/apps/contracts/scripts/deploy-pool.ts):

1. **Deploy with placeholder.** Deploy the pool with `poolJettonWallet = BURN_ADDRESS` (workchain=0, hash=0). The contract treats this as the unbound sentinel and rejects all deposits with `ERR_JETTON_WALLET_NOT_BOUND`.
2. **Compute the canonical wallet.** Off-chain, query `jettonMaster.get_wallet_address(poolAddress)` to learn the canonical pool jetton wallet (the deploy script waits \~15 seconds for state-init to settle).
3. **Bind.** Send a one-shot `AdminBindJettonWallet` op (`0xded057f4`) from the owner. The contract refuses to re-bind once the slot is non-sentinel, so this is genuinely a one-time setup.
4. **(Optional) Transfer ownership to `BURN_ADDRESS`** so admin handlers are permanently uncallable.

The pool's state-init address is computed before any TEP-74 wallet lookup, so step 1's address is stable across step 3; no rebuild needed.

## Updating the circuit

Anything that changes the circuit (new template, different hash, signal reordering) requires:

1. Updating `apps/contracts/circuits/withdraw.circom` (or `merkleUpdate.circom`).
2. Re-running `pnpm circuits:compile` (regenerates WASM + dev zkey).
3. **Re-running the ceremony** if pushing to mainnet. The old zkey is invalidated.
4. Re-running `pnpm verifier:export` to regenerate the verifier `.tolk` files.
5. Re-deploying **all pools** that use the old verifier. There is no in-place upgrade.

This is a hard reset; treat it as a v2 protocol launch.

## Mainnet gates

The mainnet deploy script ([`shell/mainnet.sh`](https://github.com/tonadocash/monorepo/blob/main/shell/mainnet.sh)) refuses to run unless:

* `MAINNET_ATTESTATION.txt` exists in `deploy/ceremony/` with valid signatures from contributors.
* `TON_NETWORK=mainnet` is explicitly set.
* `acton fmt --check`, `acton build`, and the full test suite pass.

After successful deploys it performs a "GATE 7" seed deposit, locking one pool denomination forever into the pool, so the post-deploy `nextIndex == 0 && nullifiersCount == 0` state-fresh window is closed before the pool is advertised. See [Mainnet launch plan](/operations/mainnet-launch-plan.md) for the full rehearsal.

## Adding a new pool to the registry

1. Add an entry to `packages/core/src/deployments.ts` with an empty `address: ""`.
2. Run `pnpm deploy:pool -- --network <net> --asset <a> --amount <n>`.
3. The deploy script patches the address back into `deployments.ts`.
4. `git diff packages/core/src/deployments.ts && git add packages/core/src/deployments.ts && git commit`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tonadocash.com/for-developers/deploying-pools.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
