CommitRevealVault
The CommitRevealVault is the central contract in the Specter protocol. It accepts token deposits (commits) paired with cryptographic commitments and processes privacy-preserving withdrawals (reveals) validated by ZK-SNARK proofs.
Deployed address: 0x908aA11Dc9F2e2C3F69892acaDE112e831c0a14a
Constants
uint256 public constant BN254_SCALAR_FIELD =
21888242871839275222246405745257275088548364400416034343698204186575808495617;
The BN254 scalar field modulus. All commitments and nullifiers must be less than this value.
A 5-second cooldown is enforced between consecutive operations from the same address to mitigate front-running and replay attacks.
Functions
commit
function commit(
address token,
uint256 amount,
bytes32 commitment,
bytes32 quantumCommitment
) external
Deposits ERC-20 tokens into the vault and records a commitment.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | ERC-20 token contract address. Must be authorized in AssetGuard. |
amount | uint256 | Number of tokens to deposit (in token's smallest unit). |
commitment | bytes32 | Pedersen commitment hash = Poseidon2(secret, nullifier). Must be < BN254_SCALAR_FIELD. |
quantumCommitment | bytes32 | Quantum-safe commitment (e.g., hash-based) for future post-quantum migration. |
Behavior:
- Validates
tokenis authorized viaAssetGuard.isAuthorized(token). - Transfers
amounttokens frommsg.senderto the vault viatransferFrom(requires prior approval). - Calls
CommitmentTree.recordCommitment(commitment)to insert the leaf. - Stores
quantumCommitments[commitment] = quantumCommitment. - Emits
Committed.
Reverts if:
- Token is not authorized.
- Commitment is zero or >=
BN254_SCALAR_FIELD. - Cooldown has not elapsed since the caller's last operation.
- Token transfer fails.
commitNative
function commitNative(
bytes32 commitment,
bytes32 quantumCommitment
) external payable
Deposits native GHOST tokens into the vault. The deposited GHOST is burned via NativeAssetHandler.burnNative().
Parameters:
| Name | Type | Description |
|---|---|---|
commitment | bytes32 | Pedersen commitment hash. Must be < BN254_SCALAR_FIELD. |
quantumCommitment | bytes32 | Quantum-safe commitment. |
Behavior:
- Forwards
msg.valuetoNativeAssetHandler.burnNative{value: msg.value}(). - Records the commitment in the
CommitmentTree. - Stores the quantum commitment.
- Emits
Committedwithtoken = address(0).
commitWithPolicy
function commitWithPolicy(
address token,
uint256 amount,
bytes32 commitment,
bytes32 quantumCommitment,
address policyId,
bytes32 policyParamsHash
) external
Deposits ERC-20 tokens with an attached reveal policy. The policy will be enforced during the reveal phase.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | ERC-20 token contract address. |
amount | uint256 | Number of tokens to deposit. |
commitment | bytes32 | Pedersen commitment hash. |
quantumCommitment | bytes32 | Quantum-safe commitment. |
policyId | address | Address of the policy contract implementing IRevealPolicy. |
policyParamsHash | bytes32 | keccak256 hash of the policy parameters that will be supplied at reveal time. |
Behavior:
- Performs all checks and transfers from
commit(). - Stores
commitmentPolicies[commitment] = policyId. - Stores
commitmentPolicyParamsHashes[commitment] = policyParamsHash. - Emits
Committed.
commitNativeWithPolicy
function commitNativeWithPolicy(
bytes32 commitment,
bytes32 quantumCommitment,
address policyId,
bytes32 policyParamsHash
) external payable
Deposits native GHOST with an attached reveal policy. Combines the behavior of commitNative and commitWithPolicy.
Parameters:
| Name | Type | Description |
|---|---|---|
commitment | bytes32 | Pedersen commitment hash. |
quantumCommitment | bytes32 | Quantum-safe commitment. |
policyId | address | Policy contract address. |
policyParamsHash | bytes32 | Hash of policy parameters. |
reveal
function reveal(
address token,
bytes calldata proof,
uint256[8] calldata publicInputs,
bytes32 commitment,
bytes calldata quantumProof,
bytes32 changeQuantumCommitment,
bytes calldata policyParams
) external
Withdraws funds from the vault by providing a valid ZK-SNARK proof.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | Token to withdraw (address(0) for native GHOST). |
proof | bytes | Groth16 proof bytes (BN254 curve). |
publicInputs | uint256[8] | Public inputs to the proof circuit: [root, nullifier, recipient, amount, tokenIdHash, policyId, policyParamsHash, changeCommitment]. |
commitment | bytes32 | The original commitment being spent. |
quantumProof | bytes | Quantum-safe proof data (reserved for future use). |
changeQuantumCommitment | bytes32 | Quantum commitment for any change output. |
policyParams | bytes | ABI-encoded policy parameters; must hash to the stored policyParamsHash. |
Behavior:
- Validates the Merkle
rootfrompublicInputs[0]viaCommitmentTree.isKnownRoot(). - Extracts the
nullifierfrompublicInputs[1]and checks/records it viaNullifierRegistry.checkAndRecord(). - Verifies the ZK proof via
GhostRedemptionVerifier.verifyProof(proof, publicInputs). - If a policy is attached (
commitmentPolicies[commitment] != address(0)):- Validates
keccak256(policyParams) == commitmentPolicyParamsHashes[commitment]. - Calls the policy via
staticcallwith a 100,000 gas cap.
- Validates
- Transfers tokens to
recipient(frompublicInputs[2]):- For native GHOST: calls
NativeAssetHandler.mintNativeTo(recipient, amount). - For ERC-20: transfers from vault balance.
- For native GHOST: calls
- Emits
Revealed.
Reverts if:
- Root is not known.
- Nullifier already spent.
- Proof verification fails.
- Policy validation fails.
- Token transfer fails.
Events
Committed
event Committed(
bytes32 indexed commitment,
uint256 leafIndex,
uint256 amount,
address indexed token
);
Emitted when a deposit is recorded.
| Parameter | Type | Description |
|---|---|---|
commitment | bytes32 | The Pedersen commitment hash (indexed). |
leafIndex | uint256 | Position in the Merkle tree. |
amount | uint256 | Deposited amount. |
token | address | Token address; address(0) for native GHOST (indexed). |
Revealed
event Revealed(
bytes32 indexed nullifier,
address indexed recipient,
uint256 amount,
address indexed token
);
Emitted when a withdrawal is processed.
| Parameter | Type | Description |
|---|---|---|
nullifier | bytes32 | The spent nullifier (indexed). |
recipient | address | Withdrawal destination (indexed). |
amount | uint256 | Withdrawn amount. |
token | address | Token address; address(0) for native GHOST (indexed). |
Storage
commitmentPolicies
mapping(bytes32 => address) public commitmentPolicies;
Maps a commitment to its attached policy contract address. Returns address(0) if no policy is attached.
commitmentPolicyParamsHashes
mapping(bytes32 => bytes32) public commitmentPolicyParamsHashes;
Maps a commitment to the keccak256 hash of the policy parameters that must be provided at reveal time.
quantumCommitments
mapping(bytes32 => bytes32) public quantumCommitments;
Maps a commitment to its quantum-safe counterpart, stored for future post-quantum migration.
Usage Examples
Depositing ERC-20 Tokens
// 1. Approve the vault to spend tokens
IERC20(tokenAddress).approve(vaultAddress, amount);
// 2. Compute commitment off-chain: commitment = Poseidon2(secret, nullifier)
bytes32 commitment = 0x...; // computed off-chain
bytes32 quantumCommitment = 0x...; // quantum-safe hash
// 3. Commit
CommitRevealVault(vaultAddress).commit(
tokenAddress,
amount,
commitment,
quantumCommitment
);
Depositing Native GHOST
CommitRevealVault(vaultAddress).commitNative{value: 1 ether}(
commitment,
quantumCommitment
);
Depositing with a Timelock Policy
// Encode policy params and compute hash
bytes memory policyParams = abi.encode(lockUntil, expiresAt);
bytes32 paramsHash = keccak256(policyParams);
CommitRevealVault(vaultAddress).commitWithPolicy(
tokenAddress,
amount,
commitment,
quantumCommitment,
timelockExpiryAddress, // policy contract
paramsHash
);
Revealing (Withdrawing)
// Generate proof off-chain using the Specter SDK
// proof, publicInputs are produced by the prover
CommitRevealVault(vaultAddress).reveal(
tokenAddress,
proof,
publicInputs, // [root, nullifier, recipient, amount, tokenIdHash, policyId, paramsHash, changeCommitment]
commitment,
quantumProof,
changeQuantumCommitment,
policyParams
);