Robinwood Stocks Feeds
The chain-native price layer on Robinhood Chain, published as public infrastructure — TWAP adapter feeds for every pool-priced asset the registry knows.
Chainlink prices the Stock Tokens on Robinhood Chain. Nobody prices the chain natives — the launchpad tokens and Virtuals agents that trade only on the chain's own pools. Robinwood Stocks built this layer because agentic baskets needed it; it runs in production either way, so it is published here as public infrastructure: free, keyless, no token gate.
Read the disclaimer first: these feeds answer in a Chainlink-compatible shape, and shape is not a guarantee. They are operated by Robinwood Stocks on a best-effort basis, with no SLA, no uptime commitment, and no warranty of any kind. If your protocol needs a guaranteed oracle, this is not one.
What a feed is
Every feed is an immutable adapter contract answering latestRoundData()
with a USD price at 8 decimals, built from the asset's own on-chain
market rather than any off-chain source:
- v4-pooled assets (launchpad tokens, and VIRTUAL itself): the median
sqrtPriceover a 3,600-second window of observations recorded in thePoolTwapObserver(at least 6 observations or no answer), dollarized through the quote side's Chainlink feed (USDG/USD or ETH/USD). - v2-paired assets (Virtuals agents): the pair's own cumulative-price counters, averaged against a permissionless checkpoint aged between 1,800 and 21,600 seconds, then dollarized through the VIRTUAL/USD adapter. If VIRTUAL's own feed is stale, every v2 feed refuses to answer with it.
A time-weighted price is the load-bearing choice: moving it requires holding a pool at a false price for the whole window against arbitrage, not flashing it for one block. What it costs to do that varies enormously per pool — see Honest limits below.
The interface, exactly
The adapters implement only latestRoundData():
function latestRoundData() external view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);Everything else a full Chainlink aggregator exposes does not exist here. Verified against the deployed contracts:
| Chainlink surface | These adapters |
|---|---|
latestRoundData() | yes — answer is USD, 8 decimals |
decimals() | not implemented (8 by construction; calling it reverts) |
description(), version() | not implemented |
getRoundData(roundId) | not implemented — there is no round history |
roundId / answeredInRound | constant 1; carries no information |
updatedAt | the timestamp of the newest observation in the window |
| heartbeat | none — this is a poked-observation model, not a push model |
Three return conventions matter more than anything else on this page:
updatedAt == 0means "no price". The window is not honestly covered (too few observations, checkpoint too old or too young). Treat it as the absence of a price and stop; do not readanswer.- A revert means "no price", not "retry with something else". A stale or dead upstream (the Chainlink quote feed beyond its heartbeat) makes the read revert instead of returning a lie.
- Freshness is yours to bound.
updatedAttells you when the newest observation landed. The protocol's keeper records observations around the clock (about every five minutes), but nothing guarantees that cadence — apply your ownblock.timestamp - updatedAtbound on top.
Directory
The canonical directory is the on-chain AssetRegistry at
0x53B255bff87450979c459cC91aFA47A3B93f81fb:
assetCount() / assetAt(i) enumerate the assets, assetOf(token)
returns the feed. The feed for an asset is frozen at registration and
can never be repointed — not by the curator, not by the protocol. The
table below is a verified snapshot (2026-07-28); the registry wins over
this page, always:
| Asset | Venue | Feed | Quote path |
|---|---|---|---|
| VIRTUAL | Uniswap v4 | 0x59eA6Aa8E096fE443c5e76a8e9336cF1Af56D9df | USDG pool → USDG/USD |
| CASHCAT | Uniswap v4 | 0x0De83C59558A607d8e2D9f8ED49cC1EB9321f87a | USDG pool → USDG/USD |
| TENDIES | Uniswap v4 | 0x14f7E3d665e6b24cd413842663272bC8dd8F96b0 | USDG pool → USDG/USD |
| VEX | Uniswap v4 | 0x916f21A8918B74992Fb374caEeF569711DD52a04 | USDG pool → USDG/USD |
| ARROW | Uniswap v4 | 0x60001421120bcEBD40Fbf4A96Ea2a9Be7D2363Bf | ETH pool → ETH/USD |
| HOODRAT | Uniswap v4 | 0x51B4C89f024c48fd957096A355f4309169c9C520 | ETH pool → ETH/USD |
| HAN | Uniswap v2 pair | 0xEd5db6945fe8228B36E28cc00a0DaFbfD72889ca | VIRTUAL pair → VIRTUAL/USD |
| MLY | Uniswap v2 pair | 0xbDCD4B1F896DdC113348042A2DB3b18116c9143B | VIRTUAL pair → VIRTUAL/USD |
| HYP | Uniswap v2 pair | 0x3FC2F63Dd856dD3a08bD6458b73c7a7519BfE988 | VIRTUAL pair → VIRTUAL/USD |
| MONVERA | Uniswap v2 pair | 0xB8B9D1e22Ce01737945AA967Da646d795DB37811 | VIRTUAL pair → VIRTUAL/USD |
| PRIZE | Uniswap v2 pair | 0xA8f8FF23743C65E397e05E3f222d33BFc6494722 | VIRTUAL pair → VIRTUAL/USD |
| KINDRA | Uniswap v2 pair | 0x05E84314869582558f627cc839429baF973F20BE | VIRTUAL pair → VIRTUAL/USD |
| FLETCHER | Uniswap v2 pair | 0x68A23657b1695B42BB634dCD7F72829cfe4A211c | VIRTUAL pair → VIRTUAL/USD |
| PHOOD | Uniswap v2 pair | 0xe23AEeA54Ee13F1C301A89f833968111B9fc81C3 | VIRTUAL pair → VIRTUAL/USD |
| BOWLINE | Uniswap v2 pair | 0x7bfa2bA2C295E6369C97e81A1850de40E35c861D | VIRTUAL pair → VIRTUAL/USD |
The registry also lists the Stock Tokens (AAPL, MSFT, GOOGL, AMZN, META, NVDA, TSLA, SGOV, SPY), priced by their official Chainlink feeds (8 decimals, 24h heartbeat, 24/5 with US market hours). We point at Chainlink for those and do not wrap or re-serve them.
To enumerate live:
RPC=https://rpc.mainnet.chain.robinhood.com
AR=0x53B255bff87450979c459cC91aFA47A3B93f81fb
cast call $AR "assetCount()(uint256)" --rpc-url $RPC
cast call $AR "assetAt(uint256)(address)" 0 --rpc-url $RPC
cast call $AR "assetOf(address)(address,uint32,bool)" <token> --rpc-url $RPCHonest limits
- Every native feed is currently thin, and we publish the number.
Moving VIRTUAL's TWAP by 5% costs on the order of $30k of committed
capital; every other native sits under $2k. Per-feed figures are on
app.rwoodstocks.xyz/feeds and at
/api/feeds/cost; the model is documented in Manipulation cost. Robinwood Stocks's own use is bounded by contract-level turnover and slippage ceilings; an external lending market has no such bound. Do not use these feeds for liquidation or solvency logic. - The feed is frozen, the market is not. If a canonical pool migrates or its liquidity leaves, the feed keeps reading the old pool. Inside Robinwood Stocks, delisting blocks new buys; an external integrator gets no such protection. Watch the venue you depend on.
- One keeper covers the windows today. Poking is permissionless and
anyone can run a keeper (the observer accepts one observation per second
per pool; v2 checkpoints are rate-limited to one per
minWindow/4), but if the only keeper stops, windows go uncovered and the feeds answerupdatedAt = 0until someone pokes again. That is the designed failure mode: silence, never a stale number dressed as fresh.
Ready to integrate? The consumption guide has the exact read pattern, runnable code, and the anti-pattern list.