noircashdocs

Constants

Every protocol constant and default, with its exact value, including the Pons terms NOIR trades under.

Values are read from the verified contracts. Where a value is set at deployment, the table gives the value the mainnet deployment uses; read the live value from the contract when it matters.

PrivateVault

ConstantValueMeaning
VIRTUAL_SHARES1e6Virtual shares in the share price, against the first-depositor inflation attack
GAS_MARGIN_BPS2_000 (20%)A UserOperation's fee must be worth its maximum gas cost plus this margin
MAX_PRICE_STEP_BPS1_000 (10%)A block's price (the last one poked in it) enters the average clamped to ±10% of it
EMA weight1/8ema = (ema * 7 + close) / 8: at most 1/8 × 10% = 1.25% per block
BPS_DENOMINATOR (private)10_000Basis points
SIG_VALIDATION_FAILED (private)1Returned by validateUserOp for an invalid proof
EIP-712 version"1"EIP712(name, "1"); the domain name is the constructor's name_ (TOKEN_NAME, noircash)
REGISTER_TYPEHASH (private)keccak256("Register(address owner,uint256 opk,bytes32 viewKey,uint256 nonce,uint256 deadline)")registerFor signatures
Share priceconvertToAssets(s) = s * (B + 1) / (S + VIRTUAL_SHARES)Rounds down; convertToShares is the inverse
ERC-4337 nonceuint192(nullifiers[0]) << 64One nonce key per first nullifier

The price average counts block.number, which on Robinhood Chain is the L1 block (about 12 seconds).

FeeHarvester

ConstantValueMeaning
MAX_SLIPPAGE_BPS300 (3%)A buy or gas-reserve sale must land within this distance of the price average, after Pons fees
CALLER_TIP_BPS50 (0.5%)Share of the harvested ETH paid to whoever calls harvest
MAX_HALVINGS (private)8Sizes tried for a buy or sale too large for the tolerance, halving each time (down to 1/128)
BPS (private)10_000Basis points
targetDeposit (immutable)0.1 etherEntryPoint deposit the harvester keeps for the vault

PoseidonMerkleTree

The same values hold in the circuit and in the app.

ConstantValueMeaning
TREE_DEPTH242^24 = 16,777,216 leaves per tree
ROOT_HISTORY_SIZE64Recent roots accepted by isKnownRoot; final roots of full trees stay valid forever
Empty leaf0
Insertionpairs of leaves1 + 23 = 24 tree hashes per insertion; a single note is paired with an empty leaf

NoteHash and the circuit

ConstantValueMeaning
FIELD0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 (21888242871839275222246405745257275088548364400416034343698204186575808495617)BN254 scalar field modulus
DOMAIN_NOTE1cm = H(DOMAIN_NOTE, stub, shares)
DOMAIN_NULLIFIER2nf = H(DOMAIN_NULLIFIER, nk, cm, index)
SHARES_BITS120Maximum bit size of any share amount in the circuit
SPEND_TYPEHASHkeccak256("Spend(bytes32 transaction)")EIP-712 type the wallet signs for every spend
HashPoseidon2 over BN254stub = H(opk, rho, r), opk = H(nk, wallet key limbs), tree nodes H(left, right)

Circuit and proof sizes

ItemValue
Inputs and outputs2 input notes, 2 output notes
Public inputs9: root, 2 nullifiers, 2 commitments, exit shares, extDataHash, domain separator high and low 128 bits
NUMBER_OF_PUBLIC_INPUTS in the generated verifier17
Circuit sizeN = 131072 (2^17, LOG_N = 17)
Gates83,781, of which about 73,000 check the wallet signature (measured)
Proof size9,152 bytes (PROOF_BYTES)
Proof systemUltraHonk, EVM target (keccak transcript, ZK)
On-chain verificationabout 2.35M gas (measured)
Proving timeabout 1.3 s in Node, 3 to 5 s in desktop Chrome (measured)
Toolchainnargo 1.0.0-beta.22, bb 5.0.0-nightly.20260522

Pons terms

Set by Pons V2 when it created NOIR, and frozen since. Read them from the curve (feeBps, creatorTaxBps, protocolFeeShareBps) and from factory.getLaunchedToken(noir).

TermValueMeaning
Supply1,000,000,000 NOIR (18 decimals)Minted into the bonding curve at launch
Standard fee (feeBps)100 (1%)On every trade, on the curve and on the graduated pool
Pons share (protocolFeeShareBps)3000 (30% of the standard fee)Kept by Pons
Creator tax (creatorTaxBps)0On every trade, all to the creator fee recipient (the harvester). Pons caps it with maxCreatorTaxBps()
Buybackdisabled (buybackEnabled = false)All of the creator share goes to the harvester
Trader pays1%Standard fee plus creator tax
Reaches the harvester0.7%70% of the standard fee
Fee currencyETHCredited to the Pons fee escrow; the harvester calls claim()
Graduation threshold4.2 ETH collected by the curveThen graduate and createGraduatedPool, both permissionless
Graduated poolfee 0, tick spacing 200, hook factory.memeHook()Native ETH as currency0, NOIR as currency1
Opening snipe tax99%, decaying to 0 over 5 secondsOn buys only; addresses named at launch are exempt, as Pons' rules allow
Launch phases0 not graduated, 1 swept, 2 pool createdPonsLaunchedToken.phase

Deployment values

ItemValueMeaning
Token name / symbolnoircash / NOIRNOIR's expected name and symbol, checked before deploying; the name is also the vault's EIP-712 domain name
Creator tax0NOIR's expected Pons creator tax, checked before deploying
Seed purchase0.001 etherSpent on NOIR for the locked seed note
Seed note stubkeccak256("noircash/locked-seed") mod FIELDNobody knows a preimage, so the note cannot be spent
Initial gas deposit0.1 etherInitial EntryPoint deposit for the vault
Target deposit0.1 etherHarvester target
Salt namespacenoircash-v1Salt namespace of the CREATE3 addresses
CreateX0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5EdCREATE3 factory for every noircash contract; salts are guarded by the deployer and the chain ID
Pons factory0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7ePons V2 launch factory
Pons fee escrow0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9eWhere Pons credits the creator fees
PoolManager0x8366a39CC670B4001A1121B8F6A443A643e40951Uniswap v4 PoolManager
EntryPoint0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108ERC-4337 EntryPoint v0.8

App defaults

What the noircash app uses when it builds a private transaction.

ItemValueMeaning
Verification gas limit5,500,000Validation gas limit of every private action
Call gas, sale650,000Execution gas of a sale (the swap and the ETH transfer)
Call gas, send or unshield60,000Execution gas of a send or unshield
Proof size9152 bytesThe placeholder proof used for estimates has the same size
Gas margin2,000 bps (20%)Must match the vault's
EntryPoint0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108Canonical EntryPoint v0.8
CRS points2 ** 17 (131072)CRS points the prover loads, served by the app
Note ciphertext length286 bytes32 (ephemeral key) + 1 (view tag) + 24 (nonce) + 96 + 117 (memo) + 16 (tag)
Share amount limit2 ** 120The same bound as SHARES_BITS in the circuit
Slippage100 bps (1%)Minimum output = quote × (10,000 − slippage) / 10,000
Provisional gaspreVerificationGas 1,000,000; maxFeePerGas 0.1 gwei; maxPriorityFeePerGas 1,000,000 weiUsed before the bundler's estimate, when the bundler reports no price
Fee in sharesconvertToShares(minGasFeeTokens) + 2Shares paid as the network fee
Bundler gas pricestandard × 5/4From pimlico_getUserOperationGasPrice
Bundler preVerificationGasestimate × 11/10
Bundler receipt pollingfrom every 2 s, backing off to 5 sGives up after 2 minutes
Direct submission gas20,000,000Gas of the handleOps call when the wallet submits it itself
Key-derivation Issued At2026-01-01T00:00:00.000ZFixed, so the message and the keys are deterministic
Key-derivation Noncefirst 16 hex characters of the vault address

Services

ItemValue
App domainnoircash.app
Bundlerhttps://public.pimlico.io/v2/4663/rpc
Indexer page size of /events2000 events

On this page