Architecture

The Nullmask smart contract is deployed behind a UUPS proxy for upgradeability.

Contract Hierarchy

  • NullmaskProxy (ERC1967Proxy) — delegates to:

    • Nullmask (Implementation)

      • Inherits:

        • State (storage layout)

        • Initializable

        • UUPSUpgradeable

        • ReentrancyGuardTransient

      • Calls:

        • ShieldedTransferVerifier

        • ShieldedWithdrawalVerifier

        • ShieldedSwapVerifier

      • Uses:

        • CustomLeanIMT (Poseidon2 Merkle tree)

        • Poseidon2T4Unrolled

      • Governed by:

        • AdminUpgradeController

Key Contracts

Nullmask.sol

The main privacy pool contract. Handles:

  • Deposits (ETH and ERC-20)

  • Shielded transfers, withdrawals, and swaps

  • Receiving key registration

  • Token whitelist management

  • ZK proof verification (delegates to verifier contracts)

NullmaskProxy.sol

ERC1967 proxy wrapper for UUPS upgradeability. Users interact with this address. All calls are delegated to the Nullmask implementation.

State.sol

Abstract contract defining the storage layout:

  • _noteTree — Merkle tree for note commitments

  • _keyRegistryTree — Merkle tree for receiving key hashes

  • pendingDepositHashes — Hash of pending deposit data

  • noteNullifiers — Mapping of spent note nullifiers

  • txNullifiers — Mapping of spent transaction nullifiers

  • tokenWhitelist — Token type registry

  • guard — Deposit guard address

  • upgradeController — Upgrade authorization address

  • __gap[45] — Reserved storage for future upgrades

Enums

ReceivingKey Struct

Immutables

Set in the constructor (vary per deployment):

Immutable
Description

VIRTUAL_CHAIN_ID

Virtual chain ID for this deployment

UNISWAP_V2_ROUTER

Uniswap V2 Router address on this chain

UUPS Upgradeability

The upgrade permission mechanism is itself upgradeable via setUpgradeController():

  1. Current: AdminUpgradeController — single admin (deployer)

  2. Future: Can migrate to timelock, multisig, or DAO governance

Only the current upgradeController contract can call setUpgradeController().

Public Input Validation

All public inputs are validated to be within the BN254 scalar field:

Any input ≥ FIELD_MODULUS causes the transaction to revert with PublicInputNotInField().

State Views

Admin Functions

setGuard is callable by the current guard or the upgrade controller admin. setUpgradeController is callable only by the current upgrade controller. setVerifiers requires upgrade controller authorization.

Last updated