Audit & Compliance
Reconstruct transaction history, verify completeness, and classify flows — tools for regulators, customers, and third-party auditors.
Audit & Compliance Verification
UPP provides a complete audit infrastructure that lets users prove their transaction history to regulators without compromising the privacy of other users in the pool.
Architecture
The user exports their viewing keys via the app UI. The auditor runs the upp-audit CLI against the export JSON to verify completeness, reconstruct balances, and classify transaction flows.
Audit Perspectives
UPP supports three audit perspectives, each with different trust assumptions and verification goals:
Regulator POV
A regulator needs to verify that a user's disclosed transaction history is complete — no hidden notes, no undisclosed transfers.
What they verify:
- Nonce chain is unbroken (no gaps)
- Signed
totalNoteCountmatches the chain length - All disclosed notes decrypt correctly
- Balance reconciliation matches expected flows
What they receive: Tier 1 (per-note keys) or Tier 2 (master viewing key) depending on the scope of the investigation.
Customer POV
A customer needs to prove selective disclosure — showing specific transactions to a bank or counterparty without revealing their entire history.
What they prove:
- Specific notes exist and contain claimed amounts
- Notes are linked to their account (ownership via ownerHash)
- Optional: spending proof via nullifier key
What they share: Tier 1 (specific notes only).
Third-Party Auditor POV
An independent auditor verifies the system's privacy properties work as claimed — notes are unlinkable, viewing keys are compartmentalized, and the nonce chain is tamper-evident.
What they verify:
- Per-note keys only decrypt their target note
- Master viewing key decrypts all notes but doesn't reveal spending patterns
- Nullifier key reveals spending but doesn't allow re-spending
- Nonce chain detects missing notes
upp-audit CLI
The audit CLI is a standalone verification tool that operates on exported JSON files.
Installation
# From the upp-sdk repository
npx tsx src/audit/cli.ts <command> [options]Commands
verify-completeness
Verify that an audit export contains all notes and the nonce chain is unbroken:
upp-audit verify-completeness --export audit-export.jsonChecks performed:
- Nonce chain continuity (each nonce = keccak of previous)
- Signed note count matches actual note count
- EIP-712 signature is valid for the claimed address
- All notes decrypt with the provided keys
summary
Generate a human-readable summary of the audit export:
upp-audit summary --export audit-export.jsonOutput includes:
- Total notes, spent/unspent breakdown
- Per-token balances
- Transaction flow classification (shields, transfers, withdrawals)
- Completeness status
Transaction Classification
The audit module classifies each note into flow categories:
| Category | Description | Identifiers |
|---|---|---|
| Shield | Deposit from public address | Note origin = depositor address |
| Transfer (inbound) | Received from another user | Different sender, same pool |
| Transfer (outbound) | Sent to another user | Nullifier spent, change note created |
| Withdrawal | Exit to public address | Nullifier spent, no change note |
| Merge | Note consolidation | Two nullifiers spent, one output |
Export from zkdemo-app
The ViewingKeyExport component in zkdemo-app generates the audit JSON:
- User navigates to the Viewing Keys page
- Selects disclosure tier:
- Per-note: Select specific notes to disclose
- Master key: Disclose all notes
- Include nullifier key: Optionally include Tier 3
- Signs EIP-712 note count commitment
- Downloads JSON file
The exported JSON is directly consumable by upp-audit — no manual transformation needed.
Nullifier Key Disclosure
Including the nullifier key (Tier 3) reveals which notes have been spent and where funds flowed. Only include it when required by the auditor's scope. Most compliance checks need only Tier 1 or 2.
POV Test Scenarios
The SDK includes 26 proof-of-verification tests in src/audit/scenarios/ that validate privacy properties using real cryptography (Poseidon hashing, AES-GCM encryption) against mock chain state:
- Regulator POV — completeness verification, nonce chain integrity
- Customer POV — selective disclosure, note ownership proof
- Third-party POV — privacy property validation, key compartmentalization
- Completeness POV — tamper detection, gap identification
These tests serve as executable validation of the privacy properties documented in the formal analysis.
Privacy Properties
The key hierarchy and nonce chain together guarantee:
- Compartmentalization — per-note keys can't be used to derive other notes' keys
- Completeness — omitting notes breaks the nonce chain, detectable by any auditor
- Non-spending — viewing keys and nullifier keys can't authorize transactions
- Forward secrecy — sharing a per-note key doesn't compromise future notes
- Verifiable commitment — the signed note count prevents undercounting