Documentation
How Zirplus works
Pricing, routing, sessions, halts and the contracts behind them. Everything here is enforced on-chain on Robinhood Chain; if this page and the chain ever disagree, the chain is right.
01 · Overview
A swap venue anchored to the oracle
Zirplus is a non-custodial venue for swapping tokenized stocks (Robinhood Stock Tokens) for USDG on Robinhood Chain. Every market has an anchor vault that quotes both sides around the guarded Chainlink price. Larger orders can also settle against signed RFQ quotes from market makers. A single router picks whichever venue pays more, in the same transaction.
- Prices come from a published formula, not from a pool curve, and every term is emitted on-chain with each fill.
- No fill from either venue can clear outside the market's oracle band.
- Withdrawals from a vault always work: halted, paused or retired.
- The router, vaults, factory and RFQ contract have no owner, no proxy and no sweep function.
Stock Tokens track a share's price but are a claim on their issuer, not shares registered to you. Zirplus is pre-audit software; nothing here is investment advice.
02 · Pricing
How a price is built
A vault quote is four terms over public state:
half = baseHalfSpread(tier) × sessionMultiplier ∓ skew
skew = maxSkew(tier) × (inventoryRatio − 50%) / inventoryBand (clamped to ±maxSkew)
ask / bid = mid × (1 ± half)
fee = 2 bps of the USDG sideThe mid is the Chainlink price for the exact token held in the vault. The skewalways favours the trade that brings the vault back towards 50/50, so the rebalancing side gets the tighter price. If the half-spread plus the fee would exceed the tier's oracle band, the vault returns no quote rather than a bad one.
| Tier | Half-spread | Max skew | Oracle band | Max trade (regular) |
|---|---|---|---|---|
| A | 10 bps | 15 bps | 75 bps | 50,000 USDG |
| B | 20 bps | 25 bps | 150 bps | 20,000 USDG |
| C | 40 bps | 50 bps | 300 bps | 5,000 USDG |
Fees: 2 bps on vault swaps, 2 bps on RFQ fills, and the protocol keeps 10% of the spread. LPs keep the rest.
Worked example, Tier A in the regular session: a buy at a $200.00 mid with a balanced vault pays an ask of $200.20 (10 bps), plus a 2 bps fee taken from the USDG you send.
03 · Sessions
Spreads follow the stock market
Tokens trade around the clock, but the underlying shares do not. Outside regular hours LPs carry the risk of a gap to the next open, so spreads widen and the largest allowed trade shrinks.
| Session | Hours (US standard time) | Spread | Max trade |
|---|---|---|---|
| Open | 14:30–21:00 UTC, weekdays | ×1 | ×1 |
| Extended | 09:00–14:30 and 21:00–01:00 UTC | ×1.5 | ×0.75 |
| Closed | Overnight and weekends | ×3 | ×0.5 |
Stock Tokens do not publish an on-chain market status yet, so sessions follow this weekday schedule. US market holidays are not modelled; the feed staleness bound and the move cap still protect those days.
04 · Routing
One entry point, two venues
- You call
SwapRouter.swapExactInwith the pair, an exact input, a minimum output and a deadline. You can attach a signed maker quote. - The router checks your
TRADERattestation, recomputes the vault quote in the same transaction, verifies any maker signature, and settles on whichever venue pays more. - A token-to-token swap is two atomic legs through USDG. If either leg fails its guards, the whole swap reverts.
Anything worse than your minAmountOut reverts, so the price you approve is the worst price you can get.
05 · Halts
When a market stops quoting
A market stops quoting (previews, vault fills and RFQ alike) when any of these hold:
- Stale feed.The latest Chainlink round is older than the session's staleness bound (25 hours while open, 4 days while closed, matching the feed's 24-hour heartbeat).
- Move cap. A print lands more than 25% from a checkpoint under an hour old. Anyone can call
OracleRouter.refreshto make the pause stick until governance resumes it. - Corporate action. The token reports
oraclePaused(). - Emergency pause. The guardian has paused swaps; only the owner can unpause.
Deposits need the guarded mid, so they stop too. Withdrawals never stop.
06 · Liquidity
Providing liquidity
LPs deposit the Stock Token, USDG or both into a market's vault and receive vault shares. Income is the spread the vault earns on its fills, less the protocol's 10% share, paid into the value of each share. There are no emissions and no points.
- Withdrawals are pro-rata and in kind, need no oracle, and work in every state.
- A swap never lowers value per share; rounding on mint and burn favours the vault.
- A fill can never push the vault outside its inventory band (30–70% token share). Past the band, the harmful side turns one-sided while the rebalancing side stays open.
The real risks are price exposure to the token you hold, weekend gaps (priced in by the closed-session multiplier) and the Stock Token issuer's own risk.
07 · Eligibility
Roles and attestations
Trading, providing liquidity and making markets each need a role attestation on your wallet: TRADER, LP, MAKER or RELAYER. An approved issuer writes it on-chain with only the role, a jurisdiction class, an investor class and an expiry. No personal data goes on-chain.
You never need a role to withdraw from a vault. Your attestations are listed under Account in the app.
08 · Contracts
Deployed on Robinhood Chain · 2026-10-15
Chain ID 4663. Every address links to Blockscout. There are no proxies: upgrades arrive as fresh deployments, and LPs choose whether to migrate.
| Contract | Address | Role |
|---|---|---|
| SwapRouter | 0xE5cfF6b8E51651838C74b73a4cA49202F1ed05940xE5cf…0594(opens Blockscout) | The only entry point for traders: eligibility, venue choice, two-leg swaps |
| AnchorVault · NVDA | 0x049A177583309763350e46B3CB2eAd7508c08D9d0x049A…8D9d(opens Blockscout) | Launch vault: oracle-anchored quotes, LP shares, in-kind withdrawal |
| VaultFactory | 0x762C2B13fD2c5784dBeD06Dc57A521f482BAAC0F0x762C…AC0F(opens Blockscout) | Deploys vaults and is the registry the router reads |
| RfqSettlement | 0x1c9329D6B66f610bD38ad284A435DC59B76a25d40x1c93…25d4(opens Blockscout) | Settles signed EIP-712 maker quotes inside the oracle band |
| OracleRouter | 0xb9460491694e13Afffdc13Dd578147f3323241d20xb946…41d2(opens Blockscout) | Chainlink feeds behind session, staleness and move-cap guards |
| ParamController | 0xf7D02fd1Bc8C40fd20aed40FCeD073e4081447010xf7D0…4701(opens Blockscout) | Every parameter, behind a 48-hour timelock |
| EligibilityRegistry | 0x5a65e561D94dD61c1A6C20F9A3F149559DEF72140x5a65…7214(opens Blockscout) | Role checks for traders, LPs, makers and relayers |
| NativeAttestationAdapter | 0xdA43608E348EE415857A036333ACE7e7ae25e0030xdA43…e003(opens Blockscout) | Issuer-signed role attestations, no personal data |
| FeeCollector | 0xFa35360d6f200BFDD768fD2AA3610568c5EbB13d0xFa35…B13d(opens Blockscout) | Receives swap fees, RFQ fees and the protocol's spread share |
External dependencies
| Contract | Address | Notes |
|---|---|---|
| USDG | 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d1680x5fc5…d168(opens Blockscout) | Quote asset for every market (6 decimals) |
| NVDA Stock Token | 0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC0xd060…9EEC(opens Blockscout) | Launch listing (18 decimals, ERC-8056 multiplier) |
| Chainlink NVDA / USD | 0x379EC4f7C378F34a1B47E4F3cbeBCbAC3E8E9F150x379E…9F15(opens Blockscout) | Price feed: 8 decimals, 24h heartbeat, 0.5% deviation |
09 · Governance
Governance and security
- Every parameter lives in
ParamControllerbehind a 48-hour timelock: changes are scheduled publicly and can only execute after the delay. - The guardian's only power is pausing swaps. Deposits, withdrawals and RFQ cancellation cannot be paused by anyone.
- No role can move LP or trader funds, block withdrawals or make a fill clear outside the oracle band.
Status: pre-audit. No external audit has been completed and no bug bounty is live yet. At launch the deployer key holds the owner, guardian and issuer roles; ownership moves to a multisig as the venue grows. Chainlink has not published an L2 sequencer uptime feed for Robinhood Chain yet, so that guard switches on once it exists.
Found a vulnerability? Report it privately, not in a public issue.
10 · Developers
Building on Zirplus
The router is a public contract with a stable interface. Traders approve the router; makers approve RfqSettlement. Eligibility belongs to your users' wallets, so any front end can route.
// Preview: same arguments as the swap; returns the output and the venue it would settle on
SwapRouter.previewExactIn(SwapParams) returns (uint256 amountOut, Venue venue)
// Swap: reverts if the output would be below minAmountOut or past the deadline
struct SwapParams {
address tokenIn; // USDG or a Stock Token
address tokenOut;
uint256 amountIn;
uint256 minAmountOut;
address to; // address(0) = msg.sender; any other recipient also needs TRADER
uint256 deadline;
MakerQuote quote; // optional RFQ quote, single-leg swaps only; maker = address(0) for none
bytes quoteSig;
}
SwapRouter.swapExactIn(SwapParams)AnchorVault.quoteSwapgives the exact vault preview and reverts while a market is halted; the router treats that as “no vault quote”, so RFQ can keep the market running.- The preview throws the same errors the fill would, except the deadline, eligibility and maker signature, which only the swap itself checks.
- Each fill emits mid, spread, skew and fee, so indexers can rebuild every receipt from events alone.