IShieldedPool
Title: IShieldedPool
Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)
External interface for fixed-denomination shielded (private) ERC-20 transfers. A depositor inserts a commitment into a Poseidon incremental Merkle tree; later, anyone holding the secret withdraws to an arbitrary recipient by proving, in zero knowledge, that their commitment is in the tree — without revealing which — and publishing a one-time nullifier hash that blocks double-spends.
Tornado-style. The pool provides the on-chain mechanics (commitment tree + nullifier set +
fixed-denomination ERC-20 escrow); the WITHDRAW CIRCUIT + its verifier are supplied by the
consumer (set per pool), so the cryptography is wrapped, not hand-rolled. The circuit's 5 public
signals MUST be [root, nullifierHash, recipient, relayer, fee]; the commitment is
Poseidon(nullifier, secret), the tree is the shared Poseidon LeanIMT, and nullifierHash
blocks reuse. SECURITY: this module escrows funds and must be deployed with an AUDITED circuit +
verifier and an honest trusted setup before any mainnet-with-funds use.
Functions
createPool
Creates a fixed-denomination shielded pool. Gated on the default admin role.
function createPool(address token, uint256 denomination, address verifier) external returns (uint256 poolId);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 |
|---|---|---|
| poolId | 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;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;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 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
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 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 returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | |
| root | uint256 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
Events
PoolCreated
Emitted when a pool is created.
event PoolCreated(uint256 indexed poolId, address indexed token, uint256 denomination, address indexed verifier);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | |
| token | address | |
| denomination | uint256 | |
| verifier | address |
Deposit
Emitted on a deposit.
event Deposit(uint256 indexed poolId, uint256 indexed commitment, uint256 leafIndex, uint256 merkleRoot);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | The pool. |
| commitment | uint256 | The inserted commitment. |
| leafIndex | uint256 | The commitment's leaf index. |
| merkleRoot | uint256 | The new tree root. |
Withdrawal
Emitted on a withdrawal.
event Withdrawal(
uint256 indexed poolId, uint256 indexed nullifierHash, address indexed recipient, address relayer, uint256 fee
);Parameters
| Name | Type | Description |
|---|---|---|
| poolId | uint256 | |
| nullifierHash | uint256 | |
| recipient | address | |
| relayer | address | |
| fee | uint256 |
Errors
ShieldedPoolDoesNotExist
Thrown when the pool id does not exist.
error ShieldedPoolDoesNotExist();ShieldedPoolInvalidConfig
Thrown when creating a pool with a token that has no code, a zero verifier, or a zero denomination.
error ShieldedPoolInvalidConfig();ShieldedPoolUnknownRoot
Thrown when the withdrawal root is not a known recent root of the pool.
error ShieldedPoolUnknownRoot();ShieldedPoolNullifierAlreadySpent
Thrown when the nullifier hash has already been spent.
error ShieldedPoolNullifierAlreadySpent();ShieldedPoolFeeExceedsDenomination
Thrown when the relayer fee exceeds the pool denomination.
error ShieldedPoolFeeExceedsDenomination();ShieldedPoolInvalidProof
Thrown when the withdrawal proof does not verify.
error ShieldedPoolInvalidProof();ShieldedPoolTransferFailed
Thrown when an ERC-20 transfer / transferFrom reverts, returns false, or token has no code.
error ShieldedPoolTransferFailed(address token);Parameters
| Name | Type | Description |
|---|---|---|
| token | address | The token whose transfer failed. |
Structs
WithdrawProof
A Groth16 withdrawal proof.
struct WithdrawProof {
uint256[2] a;
uint256[2][2] b;
uint256[2] c;
}Properties
| Name | Type | Description |
|---|---|---|
| a | uint256[2] | |
| b | uint256[2][2] | |
| c | uint256[2] |