Skip to content

πŸͺ™ v0.5 β€” RPL tokens, zUSD and the hardened bridge (chain 14)

Choose a tag to compare

@dendisuhubdy dendisuhubdy released this 20 Sep 02:58
· 854 commits to main since this release

πŸͺ™ RAND fullnode v0.5: RPL tokens, zUSD and the hardened bridge, live on chain 14

Released 2026-09-20 Β· chain 14 (genesis 1cff3b7d…) Β· chain cut, new genesis Β· bridged on mainnet

The fleet runs b3c594c on all 18 validators. Public JSON-RPC: https://rpc.randprotocol.org. Explorer: randscan.org. Tutorial: Deploy an RPL token Β· concept page: Tokens.

v0.5 gives RAND a token standard of its own β€” RPL, the chain's ERC-20 / SPL β€” and its first bridged asset, zUSD ("Shielded USD"): one shielded stablecoin backed 1:1 by USDT and USDC locked on Ethereum, BNB Chain, Tron and Solana. A zUSD payment is indistinguishable on chain from a RAND payment: one proof, and nobody can tell which asset moved. The release closes with a real mainnet experiment: value locked on four chains, minted, transferred privately, burned and released back β€” with the custody β‰₯ supply invariant audited at every step.


πŸ§ͺ Abstract

claim evidence
Any asset moves in one proof, the asset hidden a 4-in/4-out bundle guest with a private asset word; tier 14, ~98–109 s, 5.7 GB, 1.42 MB (measured, production FRI, CPU)
zUSD supply never exceeds custody total_supply == Ξ£ backing.locked by construction; lock and release are the only writers; audited on mainnet: custody βˆ’ locked = 0
A stolen guardian quorum cannot mint unboundedly Dilithium2 co-signature on every mint, 100 000 zUSD per backing per day cap, a pause key that can only pause
The bridge works on the deployed mainnet contracts 8 locks, 8 mints, 4 burns, 4 releases across ETH / BNB / TRX / SOL β€” every transaction linked below

🧱 Chain 14

release date 2026-09-20
chain 14, genesis 1cff3b7da248d93ab547aef5c05bb7d0d22da510b592dab9cf7374807de7c7ff (deploy/genesis-chain14.json)
pinned build fullnode b3c594c (tag v0.5 is main's tip: the same code plus the deploy record and docs)
bundle guest hc_bundle 83d3a3704a1fcdb9bae7136c0a947ffa34bd53f055388395ed705fe8cacd0ef8 (the hidden-asset guest)
validators 18, fresh keys that have never been in the repository (audit v3 OPS-1); new peer ids
tokens registration_fee 1 RAND Β· mint_cap_per_day 100 000 Γ— 10⁸ per backing Β· no token listed at genesis
bridge guardian set 0 (5-of-6 ECDSA) + six Dilithium2 PQ guardians + one pause key Β· emitters for chains 2, 3, 4, 5
faucet on (rate limited: 8 back to back, refilling at 1/s per node)
FRI profile production (80 queries)
aggregation off β€” the node refuses a genesis that carries the section until its shape is re-measured on the new bundle
call limits chain 13's five, unchanged

This is a hard fork like every format change before it: a chain-13 binary cannot run chain 14 and the reverse.


✨ New in v0.5

πŸͺ™ RPL β€” the token standard

  • A ledger-level registry, not contracts. TokenInfo { id, index, name, symbol, decimals, authority, mint_nonce, total_supply, registered_at }, folded into the state root (rand-state-4).
  • Permissionless. Anyone registers a token for 1 RAND. Symbols are not unique (as on ERC-20 and SPL); decimals ≀ 9; fees are always paid in RAND.
  • Mint authority is None, Key(Dilithium2), Bridge { backings } or Program.
  • The asset id binds everything: blake3("rand-rpl-asset", name, symbol, decimals, authority, the whole initial mint, salt) β€” a registration cannot be redirected to take the supply. Text form rpl1… (bech32m, 62 characters).
  • CLI: rand token create | mint | burn | set-authority, rand send <to> <amount> --asset <index | rpl1… | hex>, rand asset-balance.
  • RPC: rand_getTokens, rand_getToken, rand_getTokenSupply.

πŸ•ΆοΈ The hidden-asset bundle

  • One bundle per transaction, four input and four output slots. Slots 0–1 carry a private asset A; slots 2–3 carry RAND. A is not in the public digest.
  • TokenTransfer is gone: a transfer of any asset is a plain Action::None. Every transfer publishes 4 nullifiers, 4 commitments, a RAND fee and 4 envelopes β€” nothing distinguishes zUSD from RAND.
  • What stays public by design: mints and deposits, burns (burn_a, burn_asset), and the action kind of those boundary events. A transaction key or a viewing key opens a note to its full plaintext, asset included.
  • Two carry-checked conservation sums, 11 range checks, 6 + 6 pairwise distinctness checks, a fused Merkle loop whose sibling index is a program constant. A real-proof cheating suite: each case is a witness that verifies when its check is removed.

πŸ” Transaction binding

  • Every bundle proof is proved and verified against H("rand-tx-bind-1", chain_id β€– tx with proofs blanked) through the public input segment. This closes a pre-existing action-malleability hole: a proof can no longer ride a changed action, recipient or fee.

πŸ’΅ zUSD β€” one token, seven backings

  • "Shielded USD", symbol zUSD, 8 decimals, token index 1, rpl1xtj6k2x8strx8c2d5fjs50ltztck5ykms4ve7nmzmstf6fhn0v0spelqtx.
  • Backings: USDT and USDC on Ethereum, BNB Chain and Solana; USDT on Tron (Tron USDC is discontinued).
  • Registered by transaction, not by genesis: a faucet-funded deployer submitted RegisterBridgedToken and six ListBacking, each authorised by the PQ guardian quorum over fixed byte layouts.
  • A BridgeBurn names the coin it redeems. Refusals that guard the way back: NotABacking, InsufficientBacking (a coin can never release more than its own locked), NotReleasable (amount and relayer fee must be multiples of 10^(8βˆ’d)).

πŸ›‘οΈ Bridge hardening

  • B1 β€” mint cap and pause. 100 000 zUSD per backing per UTC day; PauseMints is signed by one genesis Dilithium2 key and can only pause; unpausing needs the PQ quorum. Burns and rotations stay open while paused β€” a pause never traps redemption.
  • B2 β€” bounded timestamps. A block may step at most 60 s past its parent (validity rule); a validator withholds its vote from a block more than 15 s ahead of its clock. A leader can no longer jump the clock past a cap day or a rotation's grace window.
  • B3 β€” post-quantum co-signature. Every BridgeAttest needs the 5-of-6 ECDSA quorum and a Dilithium2 quorum over "rand-bridge-pq-cosign-1" β€– chain_id β€– mu.
  • B4 β€” listing by PQ quorum after genesis, fee-paying, nonce-protected.
  • F1 β€” derived deposit blinding. r = word8(blake3("rand-deposit-r-1" β€– mu)); a relayer cannot choose or grind the deposit note.

πŸ” Found and fixed by the final review (before the cut)

  • Unbounded authority-key and KEM-key lengths (state bloat at a flat fee) β†’ exact-length rules.
  • Opaque genesis alloc commitments β†’ on a tokens chain every alloc note carries its opening and the node recomputes it at asset 0, so custody β‰₯ supply is auditable from genesis.
  • Bundle proof headers pinned to tier 14 with no keccak/sha256 table (verifier-key DoS).
  • Governance actions bypass mempool full and are ordered first β€” an emergency pause cannot be crowded out.
  • rand token create keeps the authority key unless the send itself was refused.
  • Bridge state persisted on every commit (a restart fork found by the end-to-end gate).

⚠️ Breaking changes for integrators

  • Every u64 amount in the JSON-RPC is now a decimal string β€” legacy fields included: bundle.fee; action.amount for mint, bond, unbond, withdraw, bridge_attest; action.amount and action.relayer_fee for bridge_burn; locked in rand_getAssets and rand_getBridgeState.assets[]. Indices, nonces, heights, decimals and days stay numbers. (A 9-decimal token with a 10 M supply already exceeds 2⁡³.)
  • Bundle is nullifiers[4], commitments[4], fee, burn_a, burn_r, burn_asset, time, envelopes[4]; the public asset field is gone. RAND burns go through burn_r.
  • A relayer that builds a BridgeAttest by hand must derive r (F1); rand bridge-mint does it for you.
  • Commitment tree and nullifier set grow 4 + 4 per transaction (dummies included β€” that is what makes the shapes identical).

πŸŒ‰ The mainnet experiment (2026-09-20)

Deployed endpoints, unchanged: Ethereum and BNB Chain 0xd6EBD21C3dF90c9175EBdc8d6b377a9361604892 Β· Tron TAqq2i8KfYpACPUc9f5e2gAjdSgXqmPpkU Β· Solana FGA3kY3RjfDKjUszJESMYtYXAbsnkFhhoxM3Mb34vycu. Whitelisted with small caps (100 per transfer, 1 000 per day).

Round 1 β€” 1 USDT per chain, the full round trip

chain πŸ”’ lock πŸͺ™ mint on Rand πŸ”₯ burn on Rand πŸ”“ release
Ethereum etherscan 8ac6c497… 7da01f41… etherscan
BNB Chain bscscan f2f24d75… f9f365ca… bscscan
Tron tronscan 16ea7cbd… 013ac7b7… tronscan
Solana solscan 1bb5a046… 7548f330… solscan

The shielded zUSD transfer (1.00000000 zUSD, tester β†’ a fresh demo wallet):

transaction e6ddaca3…32ed β€” on chain it is an ordinary 4-slot bundle; nothing says "zUSD"
transaction key 7f68f57c4f33a3f0fe419f4d1a5df2875461339dbc454af8ced50cbd7f40e4ef
demo wallet viewing key a93c673ffeff7204447161347828d8e549b7070460813ae1b7e664694e1dcd5d
verify it yourself rand_checkTransaction [<tx>, <tx key>] at https://rpc.randprotocol.org discloses exactly that output: amount 100000000, asset 1

The demo wallet exists only for this disclosure and holds nothing. The return transfer is d9db6ef1…0e70.

Audit after round 1 (rand-bridge-audit, mainnet): custody 0 on all seven tokens Β· accrued fees exactly 10 bps of each release Β· each endpoint's balance = custody + fees Β· Rand total_supply 0 = Ξ£ locked 0. Each release paid 0.999 USDT: the endpoints keep a 10 bps protocol fee inside the contract (accruedFees, withdrawable only by the admin through withdrawFees; it can never reach custody).

Round 2 β€” 9 USDT per chain, minted and left in place

chain πŸ”’ lock πŸͺ™ mint on Rand
Ethereum etherscan 329cce2a…
BNB Chain bscscan f74d8ba0…
Tron tronscan c2a26eec…
Solana solscan 1c7cc5b4…

End state: 36.00000000 zUSD on Rand against 36 USDT in custody β€” 9 on each chain. rand_getTokenSupply [1] reads total_supply "3600000000", locked "900000000" Γ—4; custody βˆ’ locked = 0. See it live: randscan.org/tokens/1.

The Tron/Solana mint rows are paired by the relayer's submission log (one mint proved at a time); a mint's transaction page does not yet render its source chain.


πŸ“ Measured

hidden-asset bundle proof tier 14 Β· 97–109 s on a laptop CPU Β· 5.7 GB Β· 1.42 MB
worst-case honest witness 14 242 / 16 383 cycles Β· 1 810 / 2 048 Poseidon2 permutations
end-to-end gate 9 phases, 9/9 PASS, 1 698 s: deploy by transaction, bridge in, A→B→C transfers, bridge back, every refusal, supply audit, disclosure, restart
chain-14 cut 17 droplets in ~17 min, one at a time, each waited on rand_getHealth; first block at the 13th validator
Ethereum lock β†’ mint ~15 min (the guardians wait for finalized) Β· BNB / Tron / Solana: minutes

🚧 Known limitations

  • The guardian rotation is deliberately on hold. The bridge runs on guardian set 0; a fresh set 1 and the PQ keys are generated, the rotation is the operator's call.
  • Key custody is a quorum of one: all guardian, PQ and pause keys are held by one operator. The pause key must live on another machine before real volume.
  • Pooled backing: zUSD is one token over seven coins; a depeg of one coin is shared. Accepted for v0.5; there is no Rand-side share cap.
  • The PQ quorum alone can unpause and can list up to 32 backings, each with its own daily cap.
  • A deposit's time stays submitter-chosen (≀ 257 candidate notes, all the recipient's).
  • The prover is single-threaded; aggregation is off; allowances (approve / transferFrom) are designed but not in v0.5.
  • Held for a same-chain update after re-review: the audit-v3 consensus fixes (durable locks, three-chain-only sync commits). The f+1 NewView change was dropped in favour of a timeout-certificate pacemaker in v0.6.

πŸ”— Links

  • Tutorial β€” Deploy an RPL token Β· Tokens
  • Docs β€” docs/tokens.md, docs/bridge.md, docs/rpc.md (changelog 2026-09-20), docs/cli.md
  • Specs β€” docs/superpowers/specs/2026-09-19-rpl-token-standard-design.md, …-hidden-asset-bundle-design.md, …-bridge-hardening-design.md, …-pq-cosignature-bridge.md
  • Runbook β€” docs/superpowers/handoffs/2026-09-20-chain14-cut-runbook.md
  • Explorer β€” randscan.org/tokens/1 Β· Public RPC β€” https://rpc.randprotocol.org

Full changelog: v0.4...v0.5