Skip to content
Lattice

ShieldedPool

Git Source

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

NameTypeDescription
tokenaddressThe ERC-20 token escrowed.
denominationuint256The fixed deposit/withdraw amount.
verifieraddressThe withdraw-circuit verifier; it MUST pin its key (see IShieldedWithdrawVerifier).

Returns

NameTypeDescription
<none>uint256The 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

NameTypeDescription
poolIduint256The pool.
commitmentuint256The 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

NameTypeDescription
poolIduint256The pool.
proofWithdrawProofThe Groth16 withdrawal proof.
rootuint256A known recent Merkle root the proof was built against.
nullifierHashuint256The one-time spend tag (blocks double-spends).
recipientaddressThe withdrawal recipient.
relayeraddressThe relayer paid fee (may be the recipient; fee may be 0).
feeuint256The relayer fee, &lt;= denomination.

poolCount

Returns the number of pools created.

function poolCount() external view virtual returns (uint256);

Returns

NameTypeDescription
<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

NameTypeDescription
poolIduint256

Returns

NameTypeDescription
tokenaddress
denominationuint256
verifieraddress
merkleRootuint256
numLeavesuint256

isSpent

Returns whether nullifierHash has been spent in poolId.

function isSpent(uint256 poolId, uint256 nullifierHash) external view virtual returns (bool);

Parameters

NameTypeDescription
poolIduint256
nullifierHashuint256

Returns

NameTypeDescription
<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

NameTypeDescription
poolIduint256
rootuint256

Returns

NameTypeDescription
<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

NameTypeDescription
selectorsbytes