ShieldedPool
Inherits: IShieldedPool
Title: ShieldedPool
Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)
Stateless Diamond facet for fixed-denomination shielded (private) ERC-20 transfers (Tornado-style): deposit a commitment, then withdraw to an arbitrary recipient by proving membership in zero knowledge and burning a one-time nullifier hash.
All logic lives in ShieldedPoolLib. The withdraw circuit + verifier are consumer-supplied per
pool. SECURITY: escrows funds — deploy only with an AUDITED circuit/verifier and honest trusted
setup before any mainnet-with-funds use.
CUSTODY: deposits sit in the diamond's balance with no per-module ledger. A co-cut module that counts
the diamond's whole balance of the same token (ERC-4626 totalAssets, VestingWallet release)
treats the pool's escrow as its own. One custodian per asset per diamond (issue #240).
Notes:
- lattice-version: 0.1.0
- lattice-source: Lattice original (Tornado-style; consumer-supplied audited circuit)
Functions
createPool
Creates a fixed-denomination shielded pool. Gated on the default admin role.
function createPool(address token, uint256 denomination, address verifier) external virtual returns (uint256);Parameters
| Name | Type | Description |
|---|---|---|
| token | address | The ERC-20 token escrowed. |
| denomination | uint256 | The fixed deposit/withdraw amount. |
| verifier | address | The withdraw-circuit verifier; it MUST pin its key (see IShieldedWithdrawVerifier). |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint256 | The new pool id (1-based). |
deposit
Deposits one denomination and inserts commitment = Poseidon(nullifier, secret).
Pulls denomination of the pool token from msg.sender (requires prior approval).
function deposit(uint256 poolId, uint256 commitment) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | The pool. |
| commitment | uint256 | The commitment to insert. |
withdraw
Withdraws denomination - fee to recipient and fee to relayer, against a proof.
function withdraw(
uint256 poolId,
WithdrawProof calldata proof,
uint256 root,
uint256 nullifierHash,
address recipient,
address relayer,
uint256 fee
) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | The pool. |
| proof | WithdrawProof | The Groth16 withdrawal proof. |
| root | uint256 | A known recent Merkle root the proof was built against. |
| nullifierHash | uint256 | The one-time spend tag (blocks double-spends). |
| recipient | address | The withdrawal recipient. |
| relayer | address | The relayer paid fee (may be the recipient; fee may be 0). |
| fee | uint256 | The relayer fee, <= denomination. |
poolCount
Returns the number of pools created.
function poolCount() external view virtual returns (uint256);Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint256 |
getPool
Returns pool config + state: token, denomination, verifier, current root, leaf count.
function getPool(uint256 poolId)
external
view
virtual
returns (address token, uint256 denomination, address verifier, uint256 merkleRoot, uint256 numLeaves);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| token | address | |
| denomination | uint256 | |
| verifier | address | |
| merkleRoot | uint256 | |
| numLeaves | uint256 |
isSpent
Returns whether nullifierHash has been spent in poolId.
function isSpent(uint256 poolId, uint256 nullifierHash) external view virtual returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | |
| nullifierHash | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
isKnownRoot
Returns whether root is a known recent root of poolId.
function isKnownRoot(uint256 poolId, uint256 root) external view virtual returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | |
| root | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
exportSelectors
ERC-8153 selector export: this facet's cuttable selectors, tightly packed (4 bytes each).
Excludes exportSelectors() itself (0x0ef22643) - it is never cut into a diamond. Order matches
forge inspect ShieldedPool methodIdentifiers (alphabetical by signature); kept in exact parity by
ExportSelectorsParityTest. Chunks:
createPool(address,uint256,address) 0x9bb62b76
deposit(uint256,uint256) 0xe2bbb158
getPool(uint256) 0x068bcd8d
isKnownRoot(uint256,uint256) 0xc17d30f1
isSpent(uint256,uint256) 0xe1056c3e
poolCount() 0xf525cb68
withdraw(uint256,(uint256[2],uint256[2][2],uint256[2]),uint256,uint256,address,address,uint256) 0x258702c3
function exportSelectors() external pure virtual returns (bytes memory selectors);Returns
| Name | Type | Description |
|---|---|---|
| selectors | bytes |