Introduction

RAIL20

Zero-knowledge private payments for B20 tokens on Base. Shield your balance, send privately to .rail20 usernames, swap without exposure, and stake to earn protocol revenue.

What is RAIL20?

RAIL20 is a privacy layer built on top of Base's B20 token standard (Base Beryl upgrade) and the Railgun ZK protocol. It lets users shield B20 balances into a single anonymity pool, send tokens privately to other shielded addresses, swap between B20 tokens without revealing amounts or wallets, and stake the protocol token to receive a share of fee revenue.

Unlike standard ERC-20 transfers, every interaction with the shielded pool is protected by zero-knowledge proofs. On-chain observers see only that some transaction occurred, not who sent how much to whom.

RAIL20 vs Railgun: Railgun is the underlying ZK protocol. RAIL20 is the Base-native deployment focused on B20 tokens, with native staking, .rail20 usernames, and a fee revenue model that rewards holders.

Quick Start

Get started with RAIL20 in three steps. The example below shields 100 USDbC into the private pool.

1. Connect your wallet

Visit rail20.pages.dev/app, click Connect Wallet, and approve the connection. Make sure you're on Base mainnet (chain ID 8453) or Base Sepolia (84532) for testing.

2. Approve the token

Before shielding, you need to approve the RAIL20 contract to spend your B20 tokens.

import { writeContract } from 'viem/actions'

const hash = await writeContract(client, {
  address: '0xUSDbC...',
  abi: erc20Abi,
  functionName: 'approve',
  args: ['0xRAIL20_VAULT', parseUnits('100', 6)],
})

3. Shield the tokens

Generate a ZK proof off-chain (the SDK handles this) and submit the shield transaction.

import { Rail20SDK } from '@rail20/sdk'

const sdk = new Rail20SDK({ chain: 'base' })

const tx = await sdk.shield({
  token: 'USDbC',
  amount: parseUnits('100', 6),
  recipient: alice.privateAddress,
})

// Alice's USDbC is now in the shielded pool

The first shield transaction in a session triggers a one-time proof-key download (~2 MB). Subsequent operations use the cached key.

Network & Contracts

RAIL20 is deployed on Base mainnet and Base Sepolia for testing. All contracts are open source and verified on Basescan.

NetworkChain IDStatus
Base Mainnet8453Live (25 June 2026)
Base Sepolia84532Live (18 June 2026)

Contract addresses

ContractAddress
RAIL20Vault0xRAIL20...
$RAIL20 Token0xRAIL... (via Clanker)
Staking0xSTAKE...
Username Registry0xNAME...
B20 Factory (Base)0xB20f000000000000000000000000000000000000

Shield (Deposit)

Shielding moves a public B20 balance into the RAIL20 anonymity pool. After shielding, your balance becomes part of a shared commitment tree — on-chain observers see deposits going in but cannot link them to subsequent withdrawals or transfers.

How it works

  1. Alice approves the vault to spend her B20 tokens.
  2. The SDK generates a fresh note (random secret + amount + token).
  3. A ZK proof is computed off-chain proving Alice owns the tokens.
  4. The vault verifies the proof and inserts the note commitment into the merkle tree.
  5. Alice's public balance decreases; her shielded note exists only as a commitment.

Shield parameters

ParameterTypeDescription
tokenaddressB20 token contract address
amountuint256Amount in token decimals
recipientbytes32ZK address (not Ethereum address)
feeuint256Broadcaster fee, optional

Rebase tokens: B20 rebase mode is incompatible with shielding. Make sure the B20 token has rebase disabled before depositing.

Send (Private Transfer)

Once shielded, Alice can transfer her balance to any other shielded address — including .rail20 usernames. The transfer is invisible on-chain: no amounts, no sender, no receiver.

// Alice sends 50 USDbC privately to bob.rail20
const tx = await sdk.privateTransfer({
  to: 'bob.rail20',
  token: 'USDbC',
  amount: parseUnits('50', 6),
  memo: 'thanks for lunch', // optional encrypted memo
})

What's hidden vs visible

FieldOn-chain visibility
Sender addressHidden (only broadcaster visible)
Recipient addressHidden
AmountHidden
Token typeVisible (proof commits to specific token)
TimestampVisible (block timestamp)
MemoEncrypted, only recipient can decrypt

Swap (Private Trade)

Swap one B20 token for another while preserving privacy. RAIL20 routes through Base DEX liquidity (Aerodrome, Uniswap V4) but the swap is wrapped in a ZK proof so amounts and traders stay hidden.

Fee structure

Standard swap fee is 0.25%. Stakers receive tier-based discounts down to 0.05% at Diamond tier (1M $RAIL20 staked).

const quote = await sdk.getSwapQuote({
  tokenIn: 'USDbC',
  tokenOut: 'WETH',
  amountIn: parseUnits('1000', 6),
  slippageBps: 50, // 0.5%
})

const tx = await sdk.privateSwap(quote)

Stake & Earn

Stake $RAIL20 to receive a discount on swap fees and a share of protocol revenue.

Tier benefits

TierStakeSwap FeeSavings
Standard00.25%
Bronze1,000 $RAIL200.20%17% off
Silver10,000 $RAIL200.15%33% off
Gold100,000 $RAIL200.10%50% off
Diamond1,000,000 $RAIL200.05%67% off

Lock periods

Choose your stake duration: 30, 60, 90, or 180 days. Longer locks earn boosted reward rates. Unstaking before the lock expires forfeits a portion of accumulated rewards.

Architecture

RAIL20 has four core components: the Vault (holds shielded tokens + commitment tree), the Verifier (validates ZK proofs on-chain), the Broadcaster (relays transactions for users without paying gas directly), and the Username Registry (resolves .rail20 names to ZK addresses).

Data flow

  1. User constructs a transaction off-chain via the SDK.
  2. SDK generates ZK proof using cached proving keys.
  3. Proof is sent to a broadcaster (decentralized relayer network).
  4. Broadcaster pays gas and submits the transaction.
  5. Vault verifies the proof and updates the commitment tree.
  6. Broadcaster receives a fee from the shielded pool.

Operators can run their own broadcaster to earn relayer fees. See the broadcaster repo for setup instructions.

Privacy Model

RAIL20 provides k-anonymity — your transaction is indistinguishable from any other within the shielded pool. The privacy guarantee scales with pool size.

Threat model

  • Protected against: chain analysis firms, casual observers, MEV bots, public dashboards, exchange compliance scoring.
  • Not protected against: compromised endpoint device (malware), browser-side telemetry, voluntary disclosure by user.
  • Side channels: deposit/withdraw timing correlation is mitigated by broadcaster batching and randomized delays.

Fee Structure

OperationFeeNotes
Shield (deposit)FreeGas only
Unshield (withdraw)0.10%Discounted by tier
Private transfer0.05%Plus broadcaster fee
Private swap0.25%Discounted by tier
Username registration0.005 ETH/yearBurned

Revenue Distribution

Protocol fees are split between treasury, stakers, and the buyback-and-burn mechanism.

RecipientSharePurpose
Stakers50%Pro-rata to all staked $RAIL20
Treasury30%Protocol development, ops, marketing
Buyback & burn20%$RAIL20 bought from market and burned

Smart Contracts

All contracts are open-source and verified on Basescan, written in Solidity 0.8.24+.

.rail20 Usernames

Register a human-readable name for your shielded address. alice.rail20 is easier to share than a 32-byte ZK address.

Registration

  1. Pick an available name (3+ chars, lowercase, alphanumeric + dash).
  2. Pay 0.005 ETH/year (burned, not collected).
  3. Name resolves to your ZK address via the registry contract.

Resolution is on-chain — any wallet with the registry ABI can resolve bob.rail20 to a ZK address.

FAQ

What if Railgun gets sanctioned?

Railgun is a permissionless smart contract. RAIL20 is non-custodial — there is no entity that can freeze or block users. Frontends may be geo-blocked; the contracts cannot.

Can I shield any ERC-20?

RAIL20 v1 supports B20 tokens specifically (Base Beryl spec). Future versions will add support for standard ERC-20 via a wrapper.

Why Base?

Base is fast, cheap, and the B20 standard provides native rebase + privacy primitives that aren't available on other L2s.

How do I become a broadcaster?

Run the broadcaster node (Docker image), stake at least 10,000 $RAIL20, and register your endpoint with the protocol. Earn 100% of relayer fees on the txs you submit.

What's the difference between RAIL20 and a mixer?

RAIL20 uses a single anonymity pool with continuous deposits and withdrawals — it's not a fixed-denomination mixer. There are no withdrawal time windows.

Can I see my own balance?

Yes. Your wallet derives notes locally and shows your shielded balance in the app UI. Only you can see it.

Is staking risky?

Staking has a lock period — you can't withdraw before the lock expires without forfeiting rewards. The contract has no admin keys to confiscate stakes.