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 hashespendingDepositHashes— Hash of pending deposit datanoteNullifiers— Mapping of spent note nullifierstxNullifiers— Mapping of spent transaction nullifierstokenWhitelist— Token type registryguard— Deposit guard addressupgradeController— Upgrade authorization address__gap[45]— Reserved storage for future upgrades
Enums
ReceivingKey Struct
Immutables
Set in the constructor (vary per deployment):
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():
Current:
AdminUpgradeController— single admin (deployer)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