> For the complete documentation index, see [llms.txt](https://plabs.gitbook.io/plabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://plabs.gitbook.io/plabs-docs/privacy-core/shield-erc20/deployment.md).

# Deployment & factory

## One-time infra (per chain)

Reuse the same Groth16 verifier as pERC20 — **no new circuit or trusted setup**.

| Contract                | Role                                             |
| ----------------------- | ------------------------------------------------ |
| `ActionGroth16Verifier` | Shared with pERC20 (reuse existing deploy)       |
| `ERC20ShieldFactory`    | EIP-1167 clones + `(underlying, scale)` registry |

Deploy `ERC20ShieldFactory(groth16VerifierAddress)` once per chain. The factory deploys a locked `ERC20Shield` implementation internally.

## Create a shield pool

A **shield pool** is one `ERC20Shield` instance — custody for a single `(underlying, scale)` pair. Value enters only via `shield` and exits via `unshield`.

```solidity
address pool = factory.createShieldPool(
    "Shield USDC",    // name  — metadata only
    "sUSDC",          // symbol
    6,                // decimals (display; suggest matching underlying)
    usdcAddress,      // underlying ERC-20
    0                 // scale: 0 → use suggestedScale(underlying.decimals())
);
```

* **Permissionless** — anyone may deploy for any ERC-20
* **One pool per `(underlying, scale)`** — duplicate reverts `PoolExists(existing)`
* Deployer becomes **`admin`** (compliance: `setFrozenRoot`, `setGroth16Verifier`)
* Emits `ShieldPoolDeployed` and pool-local `ShieldPoolCreated`

### Deterministic address (CREATE2)

```solidity
address pool = factory.createShieldPoolDeterministic(
    name, symbol, decimals, underlying, scale, salt
);
address predicted = factory.predictShieldPoolAddress(creator, salt);
```

Salt is mixed with `msg.sender`: `keccak256(abi.encode(creator, salt))`.

## Scale selection

Note values are constrained to **64 bits** in the action circuit. `scale` maps note units to underlying wei:

```
weiAmount = amountUnits * scale
```

### `suggestedScale(tokenDecimals)`

| Underlying decimals | Default `scale`     | Note unit granularity     |
| ------------------- | ------------------- | ------------------------- |
| ≤ 8                 | `1`                 | 1 wei                     |
| > 8                 | `10^(decimals − 8)` | `10⁻⁸` of one whole token |

Example: 18-decimal token → `scale = 1e10` → one note unit = `1e-8` token.

Pass `scale_ = 0` to `createShieldPool` to auto-resolve via `suggestedScale`. Custom scales are allowed but **`scale` is fixed at init** — choose carefully before deployment.

Constraints enforced on-chain:

* `amountUnits < SUBGROUP_ORDER` (same as pERC20 mint/burn)
* Dust `< scale` wei cannot be represented as a note unit

## Registry

| Mapping                                 | Purpose                                  |
| --------------------------------------- | ---------------------------------------- |
| `isShieldPool[pool]`                    | `true` for factory-deployed shield pools |
| `poolFor[keccak256(underlying, scale)]` | First shield pool for each pair          |

Wallets and coordinators should verify `isShieldPool(pool)` before treating an address as a legitimate shield pool.

## Admin roles

| Role                          | Powers                                                | Notes                                       |
| ----------------------------- | ----------------------------------------------------- | ------------------------------------------- |
| `admin` (deployer by default) | `setFrozenRoot`, `setGroth16Verifier`, admin transfer | **No mint** — cannot create unbacked supply |
| `issuer()` view               | Returns `admin`                                       | IPERC20 compatibility only                  |

For shield pools, **`setGroth16Verifier` is a high-trust action** — a malicious verifier could authorize forged `unshield` proofs and drain custody. Same trust model as pERC20, with real ERC-20 at stake.

## Clone initialization

EIP-1167 clones call `initialize(...)` atomically in the factory transaction — no init front-running window. The locked implementation is fully initialized at factory deploy and cannot be hijacked.

## Multi-chain

Same bytecode per chain; binding signatures include `chainId` and `address(this)`. Each chain needs its own factory + per-asset pool clones.

→ [Multi-chain deployment](/plabs-docs/ecosystem/multichain.md)

## Tools

| Tool           | Path                                                         |
| -------------- | ------------------------------------------------------------ |
| Deploy scripts | `script/DeployOfficial.s.sol`, `script/deploy-all-chains.sh` |
| Tests          | `test/ERC20ShieldTest.t.sol`                                 |
| Design notes   | `docs/shield-unshield-and-swap.md`                           |

## Next

* [Shield ERC20 overview](/plabs-docs/privacy-core/shield-erc20/overview.md)
* [pERC20 issuance](/plabs-docs/privacy-core/perc20/issuance-and-deployment.md) (shared verifier infra)
* [Shield pool 命名变更说明](https://github.com/PLabs4/docs/blob/main/docs/shield-pool-naming-migration.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://plabs.gitbook.io/plabs-docs/privacy-core/shield-erc20/deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
