Deployments
Network details, contract addresses, the Pons contracts NOIR trades on, and the public bundler of noircash on Robinhood Chain.
Network
| Field | Value |
|---|---|
| Network | Robinhood Chain |
| Chain ID | 4663 |
| RPC URL | https://rpc.mainnet.chain.robinhood.com |
| Explorer | robinhoodchain.blockscout.com |
| Native currency | ETH, 18 decimals |
| App | noircash.app |
On Robinhood Chain, block.number follows the Ethereum L1 block, about 12 seconds. The vault's price average
counts these blocks (see Gas).
noircash runs only on Robinhood Chain mainnet, because Pons V2, the launchpad NOIR is created on, exists only there.
Contract addresses
| Contract | Address | What it is |
|---|---|---|
| NOIR | 0xDa2E4659dA030AEd0285F9Ed3496ec07058b2319 | The token: a plain ERC-20 created by Pons V2, no owner, no transfer restrictions |
| Pons bonding curve | 0x7D1e90200654C2BE3e3a0eC035bC7Fa3C55f026f | Where NOIR trades against ETH until it graduates. Pons' contract, one per token |
PrivateVault | 0x0a55A88524002dd8F053Ffc644015EDc9653963a | Holds shielded NOIR: key registry, note tree, nullifiers, vault shares, price average, and the ERC-4337 account of private actions |
PrivateRouter | 0x00fe9533Df78aF8e59cF8BC0EcDDe551140920D5 | Buys NOIR into a note, sells a note for ETH, quotes |
FeeHarvester | 0x76d4979272019475b7eD690d5943E14296bDcDd6 | NOIR's Pons creator fee recipient; receives the creator fees in ETH and turns them into gas and holder yield |
HonkVerifier | 0xeA05c34fF6a60EBF6E73544E449B0DE7095C7941 | UltraHonk verifier of the transact circuit |
| Poseidon2 hasher | 0x33E32aa162d637F149924ab025DAcA55E1571842 | Poseidon2 over BN254, used by the note tree |
NOIR's and the curve's addresses are chosen by Pons when it creates NOIR. Pons' record of the token names the
harvester as its creator fee recipient: factory.getLaunchedToken(noir).creatorFeeRecipient.
Pons V2
| Contract | Address |
|---|---|
PonsV2LaunchFactory | 0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e |
PonsV2MemeHook (the factory's memeHook()) | 0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044 |
| Pons fee escrow | 0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9e |
The router and the harvester read the hook from factory.memeHook() at deployment, and it is the address above.
Shared infrastructure
| Contract | Address |
|---|---|
Uniswap v4 PoolManager | 0x8366a39CC670B4001A1121B8F6A443A643e40951 |
ERC-4337 EntryPoint v0.8 | 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108 |
| CreateX | 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed |
Deterministic addresses
Every noircash contract is deployed through CreateX's CREATE3, with a salt that only the deployer can use and that
includes the chain ID. An address therefore depends only on the deployer, the chain and a salt label
(noircash-v1), not on the contract's bytecode. The mainnet deployer is
0x0a0C4DD333E2A29a92321Ce32d155e800101c1bf, so the noircash addresses above are fixed before deployment. NOIR's
and the curve's addresses are not: they are set by Pons.
Where NOIR trades
NOIR trades in two places over its life, both run by Pons:
- The bonding curve, from launch until it has collected 4.2 ETH.
- The graduated Uniswap v4 pool, after that. Graduation takes two permissionless calls on the factory,
graduate(sweeps the curve) andcreateGraduatedPool(seeds the pool). The router and the harvester make them themselves on the next trade if nobody else has.
The graduated pool's PoolKey:
| Field | Value |
|---|---|
currency0 | 0x0000000000000000000000000000000000000000 (native ETH) |
currency1 | NOIR, 0xDa2E4659dA030AEd0285F9Ed3496ec07058b2319 |
fee | the launch's poolFee (0) |
tickSpacing | the launch's tickSpacing (200) |
hooks | PonsV2MemeHook, 0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044 |
Only the Pons factory can initialize a pool with its hook, so nobody can open this pool first. A pool with any other key (another fee, tick spacing or hook) has another pool id and is ignored by the router, the harvester and the price average. Fees are the same before and after graduation. See The pool.
Aggregators already route Pons tokens on Robinhood Chain, on the curve and on graduated pools. See Integrations.
Bundler
Private actions (send, sell, unshield) reach the chain as ERC-4337 UserOperations whose sender is the vault. The app uses Pimlico, which lists Robinhood Chain (4663) with EntryPoint v0.8:
| Field | Value |
|---|---|
| Endpoint | https://api.pimlico.io/v2/4663/rpc?apikey=… with the app's key; without a key, the public https://public.pimlico.io/v2/4663/rpc |
| Rate limit | 5,000 requests per minute with a key; 20 per minute per IP on the public endpoint |
| EntryPoint | v0.8, 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108 |
The API key ships in the page, so it is restricted on Pimlico's side: to the vault as the only contract, to the
app's origin, with no sponsorship policy and a low spending cap. The vault rejects any operation with
paymasterAndData, so the key cannot be used to sponsor gas. The app talks to Pimlico directly, not through a proxy
of ours that would see users' IP addresses next to their operations.
Limits that matter:
- Rate limit. One private action makes a few requests: a gas price, an estimate, the send, then receipt polls from every 2 seconds backing off to 5. On the public endpoint, several actions in a row from one IP can hit 20 per minute.
- Validation gas. The app does not use the bundler's validation estimate, which is far above what a private
transaction uses. It sets
verificationGasLimitto its own 5,500,000 and takes onlypreVerificationGasfrom the bundler. - Gas price. The app reads it with
pimlico_getUserOperationGasPrice, a Pimlico method, and pays 1.25 times thestandardprice.
Any ERC-4337 bundler that supports EntryPoint v0.8 can be used instead.