NullNet

github.com/NullNetProtocol/null-chain — 37a77c47edb7db9a45040089ac3b18963c377ade

Audit date ·

Audits are prepared by the site owner with a self-hosted (local) AI, checked against the exact commit above, and hand-edited before publishing. This is not financial, legal, or investment advice. Read it as one person's notes on one commit at one date. Do your own research.

This is a point-in-time review of code quality and tokenomics at the commit above, not a safety certification. Projects can change after this date. Check for newer releases or a newer audit before relying on these scores.

Shielded-only ZK L1 in Rust; issuance is a pure function of height and proven by the binding signature. A 3% premine sits under one key with no timelock or multisig.

Code 9 · Tokenomics 7 · Risk 7 · MIXED

🪙 NULLNET (NULL) — Code & Tokenomics Audit

Repo: NullNetProtocol/null-chain at commit 37a77c47edb7db9a45040089ac3b18963c377ade
Date: 2026-10-19 Scope: recon, code review (subsidy, issuance enforcement, coinbase balance, block validation, wallet), tokenomics. The circuit was read as a statement, not cryptanalytically verified. No chain is live, so on-chain supply is unverified.

🎯 Verdict: MIXED (risk 7.0)

NullNet is a shielded-only ZK chain written from scratch in Rust, and it is the most disciplined codebase in this set. Issuance is a pure function of height, the validator recomputes the coinbase balance from subsidy(height) + fees and the binding signature must prove exactly that number, so a coinbase cannot claim more or less than the rule allows. There is no unsafe in the consensus crates, arithmetic is checked everywhere, CI runs on three platforms and the release workflow builds the shipped artifacts with SHA-256 sums. It lands in MIXED for two things: a 3 % premine (630,000 coins) paid to a development fund held by a single key with no timelock and no multisig — the project says so itself — and the fact that on a shielded chain the supply cap cannot be observed, only enforced per transaction. This scores code and tokenomics only.

🔑 At a glance

FieldValue
ProjectNullNet (NULL)
Chain / consensusOwn L1, Equihash (144,5) PoW, 120 s blocks, shielded-only Halo2 circuit
Code score9.0 / 10
Tokenomics score7.0 / 10
Risk score7.0 / 10 (the lower of the two)
VerdictMIXED

🔗 Links & sources

WhatLinkStatus
🏠 Homepage—
💻 Source✅ cloned in this audit
🔎 Explorer—
📄 Whitepaper—
📣 Announcement—
💬 Socials—

🧮 Risk score inputs

#Findingfile:lineReachableDeductionApplies to
1The circuit range-checks note values to 64 bits, which is wider than MAX_MONEY; the cap is enforced only by the per-transaction balance equation and by parsing, not in-circuit. On a shielded chain no node can observe total supplycrates/circuit/src/gadgets/range.rs:28-43, crates/protocol/src/amount.rs:14-33live−0.5code
2The genesis coinbase must be regenerated by hand at launch; every run produces a new proof and a new genesis hash that must be re-pinned. The project states that a launch which forgets to regenerate it would burn the preminecrates/chain/src/genesis.rs:51-58, docs/decisions.md:890-895live at launch−0.5code
3Premine 630,000 coins = 3 % of MAX_MONEY, paid by the genesis coinbasecrates/protocol/src/consensus.rs:47, docs/params.md:56live−1.0tokenomics
4The development fund is a live spending key with no timelock and no multisig; the project admits the code does not solve its custodydocs/decisions.md:894live−2.0tokenomics

Code deductions, one at a time:
0.5 → 1.0

code_score = 10 − 1.0 = 9.0

Tokenomics deductions, one at a time:
1.0 → 3.0

tokenomics_score = 10 − 3.0 = 7.0

risk_score = min(9.0, 7.0) = 7.0

Instant override check: none fired. All five checked — (1) no key, role or admin path can mint outside the height-determined schedule; the only value creation is the coinbase balance the validator recomputes; (2) nothing sends seed, key or wallet contents anywhere — no telemetry, no analytics, no outbound calls in the code; (3) no backdoor, killswitch or remote-code path found; (4) not a fork presented as original work — it is written from scratch, and the design sources (Zcash, Halo2, Poseidon, RedPallas) are named; (5) no doc claim about supply or privacy contradicted by the code — the emission arithmetic was recomputed and matches, and the privacy claims are stated with what leaks.

🔒 Code

Commit audited: 37a77c4

📊 Tokenomics

ItemValueEvidenceFlag
Premine630,000 coins = 3 % of MAX_MONEY, paid by the genesis coinbase to the development fundconsensus.rs:47, docs/params.md:56, docs/decisions.md:868⚠️ disclosed, 1–5 % band
Mint authoritynone outside the coinbase balance the validator recomputesvalidate.rs:295, protocol/validate.rs:56✅
Issuance enforced in consensusyes — recomputed per block and proven by the binding signatureconsensus.rs:58-65, validate.rs:295✅
Hard cap21,000,000 coins. Enforced by the balance equation and by parsing, not in-circuitamount.rs:14, range.rs:28⚠️ enforced but unobservable
Emission curve9.7 coins at height 1, halving every 1,050,000 blocks. Recomputed independently: 20,999,999.8845 coins, 0.1155 under the capconsensus.rs:49-53, test consensus.rs:181-200✅
Docs vs codeparams.md says emission plus premine "sums to MAX_MONEY"; the code sums to 0.1155 coins less. threat-model.md says "sum below MAX_MONEY", which is the accurate wordingparams.md:50 vs threat-model.md:44⚠️ loose wording, code is stricter
Dev or founder share0 % of the subsidy — no founders' output, no dev fee. The project rejected per-coinbase founder outputs and a private mining perioddocs/decisions.md:870-878✅
Treasurythe premine is notes under one key, held offline. No timelock, no multisig. The project says custody is a key-management question the code does not solvedocs/decisions.md:894❌ live spending key
Genesis reproducibilityyes — the coinbase bytes are committed in crates/chain/src/genesis/main.tx and the hash is pinned by a test (genesis.rs:80-88)genesis.rs:80-88✅
Premine historyreduced from 5 % to 3 % on 2026-10-15, and the initial subsidy raised from 9.5 to 9.7 so the cap still holdsdocs/decisions.md:901-910✅

🕵️ Privacy

🚩 Red flags

✅ Green flags

📋 Context (does not affect the score)

SignalValue
Contributors / commits / repo age1 author (NullNetDev <[email protected]>), 23 commits in the depth-50 clone, repo created 2026-09-28
AI-assisted commitsthe repo carries a CLAUDE.md engineering-rules file; the decisions log reads as AI-assisted. Not deducted
Relaunch, rename or fork lineagenone; written from scratch, sources named
Independent auditno — docs/audit.md is an internal review, self-labelled as not independent
Launch-stage items not deductedno checkpoints (params.md:33), no DNS seeds, five unnamed seeds, no listing, no liquidity, no live chain, single author — recorded, not scored
Public RPC or explorer reachableno chain yet
Market datanot relevant at this stage
Hashrate, power cost, profitabilityout of scope

❓ What I could not check

🧭 Bottom line

The best-engineered money path in this group: issuance is a pure function of height, recomputed inside validation, proven by the binding signature, and the premine is tested to pay exactly its stated amount. What keeps it in MIXED is that a shielded chain cannot show its supply, and that 3 % of it sits under one key with no timelock or multisig. To reach MIXED in the scored areas: add the MAX_MONEY bound as a circuit constraint so the cap is proven rather than parsed, put the development fund under a timelock or a multisig, and get the circuit formally verified. The project already lists all three as launch requirements.

Files we opened

crates/protocol/src/consensus.rs:58-65

crates/chain/src/validate.rs:295

crates/protocol/src/validate.rs:56-60

crates/circuit/src/gadgets/range.rs:28-43

crates/protocol/src/amount.rs:14-33

crates/chain/src/genesis.rs:51-58

docs/decisions.md:894

crates/chain/src/validate.rs:72-97

crates/protocol/src/consensus.rs:181-200

crates/wallet/src/wallet.rs:73-77

Every file listed here was opened by us during the audit. Nothing here is a guess.

Back to Projects