Docs

How Gapfill works

Everything behind the numbers: what the weekend gap is, how rounds and scores work, where every price comes from, and how to use the data yourself.
Getting started

Introducing Gapfill

Gapfill is weekend gap research for stock tokens on Robinhood Chain. The tokens trade around the clock in Uniswap v3 pools, but the Chainlink price feeds that smart contracts read follow US market hours. Every weekend the oracle holds Friday's price while the pools keep moving. Gapfill measures that gap live and scores who can call where it closes.

It is built for three kinds of people:

  • Traders who want to see how far each pool has drifted from the frozen oracle price.
  • Builders and lenders who need a free, keyless record of weekend risk on stock tokens.
  • Agent builders who want a scored game: call where the oracle reopens and let the oracle decide.

Live today: the gap board for 26 stock tokens, weekend rounds with a live timeline, a backtest leaderboard over 10 weekends and 170 calls, and public JSON endpoints. Next: onchain calls, so any agent can enter.

Quick start

  1. Open the gap board. Each row shows the oracle price, the pool price and the gap between them.
  2. Check the session pill in the header. It says Oracle live on weekdays and Oracle frozen from Friday 20:00 to Sunday 20:00 New York time, with a countdown.
  3. Follow the round on How a round works: the freeze, calls lock, reopen and settle times of the current weekend, in New York time and your own.
  4. See who called it best on the leaderboard, where four baseline agents are scored on every weekend since mainnet.
  5. Building something? Pull every address from the public API and read the chain yourself.
Concepts

Why the gap exists

Stock tokens on Robinhood Chain are standard ERC-20s that trade 24/7 on Uniswap, Lighter, Rialto and other venues. Their Chainlink feeds are tagged us_equities_24/5: while the session is open they update on a 0.5% move or a 24-hour heartbeat, and while it is closed they do not update at all.

So every weekend the oracle holds Friday's price while the pools keep trading. Lending markets that value stock tokens with that oracle are exposed to the difference, and the first oracle round after the reopen settles it. That difference is the weekend gap.

Reading the gap

Gap = pool price ÷ oracle price − 1, in percent. The pool price is converted to USD first, so both sides are in the same unit.

  • Positive: the pool trades above the oracle. Traders have priced the stock higher since the oracle last moved.
  • Negative: the pool trades below the oracle.
  • On weekdays gaps stay small, because the oracle follows the market on every 0.5% move. On weekends they can grow, because the oracle cannot move at all.
  • The bars on the board share one scale, set by the largest gap on screen, so you can compare rows at a glance.

A real example from round #11 (Sep 11 – Sep 13): by the Sunday cutoff the SNDK pool had moved −3.89% from the freeze while the oracle held $1,635.11. At the reopen the oracle settled at $1,548.83, an oracle gap of −5.28%.

Market hours and holidays

The feeds follow the 24/5 equity session. The session for trading day D runs from 20:00 New York time on the day before D to 20:00 on D, so in a normal week it is open from Sunday 20:00 to Friday 20:00. All times are New York time, which moves between EST and EDT with daylight saving.

NYSE full-day holidays close the session for that day. A Friday holiday moves the weekend freeze to Thursday 20:00, and a Monday holiday moves the reopen to Monday 20:00. Gapfill knows these closures:

2026
  • Thu, Jan 1
  • Mon, Jan 19
  • Mon, Feb 16
  • Fri, Apr 3
  • Mon, May 25
  • Fri, Jun 19
  • Fri, Jul 3
  • Mon, Sep 7
  • Thu, Nov 26
  • Fri, Dec 25
2027
  • Fri, Jan 1
  • Mon, Jan 18
  • Mon, Feb 15
  • Fri, Mar 26
  • Mon, May 31
  • Fri, Jun 18
  • Mon, Jul 5
  • Mon, Sep 6
  • Thu, Nov 25
  • Fri, Dec 24

A round is a closure that contains a Saturday. A mid-week holiday also freezes the oracle for a day, but it is not a round. The holiday list is extended every year.

Oracle feeds

Each stock token has its own Chainlink data feed on Robinhood Chain, listed in Chainlink's feed directory as an equity feed. Gapfill reads the feed proxy with latestRoundData().

  • Update rule: while the session is open, a new round on a 0.5% price move or after a 24-hour heartbeat. While it is closed, no rounds at all.
  • Decimals: prices come with 8 decimals.
  • Round ids: the proxy packs the feed phase into the top bits. The site shows the underlying aggregator's round number.
  • USDG / USD: a separate feed converts pool prices from USDG to USD on the live board.

Pool prices

For each stock token Gapfill uses the Uniswap v3 pool against USDG with the most in-range liquidity across the 0.01%, 0.05%, 0.3%, 1% fee tiers. Today that is 7 pools at 0.05%, 12 pools at 0.3%, 7 pools at 1%.

  • The price comes from the pool's current sqrtPriceX96, adjusted for 18-decimal stock tokens against 6-decimal USDG.
  • It is a mid price: what the next tiny trade would pay, not what a large order can fill at. Thin pools can drift far from the oracle on any day.
Rounds and scoring

Rounds

Every weekend is one round, defined in New York time:

  • Freeze: 20:00 on the last trading day before the weekend, when the 24/5 session closes.
  • Calls lock: 8 hours before the reopen (Sunday 12:00).
  • Reopen: 20:00 on the eve of the next trading day (Sunday 20:00), when the feed posts its first round.
  • Settle: 1 hour after the reopen. Calls are scored on the oracle price in force at that moment.

NYSE holidays stretch a round: when Friday is a holiday the freeze moves to Thursday, and when Monday is one the reopen moves to Monday night. The feed history on Robinhood Chain matches this schedule for every weekend since launch, including July 3 and Labor Day.

Scoring

  • Pool move = pool price at the cutoff ÷ pool price at the freeze − 1. This is what an agent can see.
  • Oracle gap = oracle price at settlement ÷ oracle price at the freeze − 1. This is what an agent is scored on.
  • Error = |called gap − oracle gap|, in percentage points. The leaderboard ranks by mean error.
  • Direction hit = share of calls with the right sign, among gaps of 0.1% or more.
  • Skill vs pool = 1 − error ÷ AMM Annie's error. Positive means the agent beat simply trusting the pool.
  • Weekend carry β = least-squares slope, through the origin, of oracle gap on pool move across all markets and weekends: the share of the weekend move that shows up at the reopen. It is 0.82 today (R² 0.52).

Baseline agents

Four rule-based agents play every round. Each calls the oracle gap as a fixed multiple k of the pool move. Their scores over 10 weekends:

AgentkAvg errorDirection hitSkill vs poolWeekends won
AMM Annie1×0.79 pp70.7%baseline4
Fader0.5×0.80 pp70.7%−1.4%0
Flat Frank0×0.95 pp−21.3%5
Momentum Mo1.5×0.98 pp70.7%−24.7%1
  • AMM Annie: Calls the reopen at the pool's weekend price: the whole weekend move carries.
  • Fader: Calls half of the pool's weekend move: the rest fades before the oracle wakes up.
  • Flat Frank: Calls no gap at all: the oracle reopens at its Friday price.
  • Momentum Mo: Calls 1.5× the pool's weekend move: weekend moves extend into the reopen.
Data

Method and data

Every number on this site comes from public sources, with no API keys anywhere:

  • Chainlink's feed directory for Robinhood Chain, for the equity feeds and the USDG/USD feed.
  • Robinhood's public stock token registry, for token addresses and names.
  • Uniswap v3 on Robinhood Chain (factory 0x1f7d7550b1b028f7571e69a784071f0205fd2efa): for each token, the pool against USDG (0x5fc5360D) with the most in-range liquidity.
  • Robinhood Chain RPCs and the explorer for evidence links.
  • Company logos from the Elbstream Logo API (SpaceX from Simple Icons), shown only to identify each stock. The logos are trademarks of their owners.

The backtest needs no archive node. Oracle history comes from the feeds' AnswerUpdated events and pool prices from Uniswap Swap events. It was last rebuilt at block 66,109,625.

Data quality

  • Median of swaps. The pool price at a moment is the median post-swap price of the last 5 swaps before it, searched backwards in widening windows. One swap through an empty liquidity range can't set it.
  • Thin pools are left out. A market-weekend is dropped when its pool was already more than 3% away from the oracle at the freeze (23 so far), or moved more than 20% before the cutoff (2 so far). 0 had no usable price. That is 25 left out in total.
  • USDG as a dollar. The live board converts USDG with its oracle feed. The backtest treats USDG as $1 across a weekend, where it cancels out of the pool move.
  • Mid prices. Pool prices are not executable prices for size.

Supported markets

A stock token is tracked when it has an oracle feed and a Uniswap v3 pool against USDG with in-range liquidity. 26 markets qualify today. Links open the explorer.

MarketPool feeTokenFeedPool
AAPL0.05%tokenfeedpool
AMD0.3%tokenfeedpool
AMZN0.3%tokenfeedpool
ASML1%tokenfeedpool
BABA0.3%tokenfeedpool
CRCL0.3%tokenfeedpool
DELL1%tokenfeedpool
GME0.05%tokenfeedpool
GOOGL0.05%tokenfeedpool
INTC0.3%tokenfeedpool
IONQ1%tokenfeedpool
META0.3%tokenfeedpool
MSFT0.3%tokenfeedpool
MSTR1%tokenfeedpool
MU0.3%tokenfeedpool
NVDA0.05%tokenfeedpool
PLTR0.3%tokenfeedpool
QQQ0.05%tokenfeedpool
RKLB1%tokenfeedpool
SLV0.3%tokenfeedpool
SNDK1%tokenfeedpool
SPCX0.05%tokenfeedpool
SPY0.05%tokenfeedpool
TSLA0.3%tokenfeedpool
TSM1%tokenfeedpool
USO0.3%tokenfeedpool

Left out for now, with a feed but no USDG pool with liquidity: EWY, COIN, RGTI, ORCL, NBIS, CLSK, CRWV.

How live data is read

  • The board refreshes every 30 seconds while the page is open, and pauses while the tab is hidden.
  • It first asks /api/snapshot, which reads every market in batched RPC calls and caches the result for 15 seconds.
  • Public RPCs rate-limit the shared IPs of cloud hosts. When the server can't reach the chain, your browser reads it directly through PublicNode for the rest of the visit, with the same formulas.
  • “Read from chain” above the board shows how old the latest read is.
Build

Public API

Gapfill's data is free to use. No keys, no sign-up. Please cache what you fetch and poll no more than every 30 seconds.

  • GET /api/markets: every tracked market with its token, feed and pool addresses, decimals and fee tier, plus the USDG / USD feed.
  • GET /api/backtest: the full backtest, with rounds, agent scores, the carry fit, quality settings and every observation with its onchain evidence.
  • GET /api/snapshot: the live read. It is best effort: it answers 502 while public RPCs rate-limit the host. For live prices you can rely on, read the chain directly with the addresses from /api/markets.
Snapshot fieldMeaning
atWhen the chain was read (ISO time).
sessionOpenWhether the 24/5 equity session is open right now.
usdgUsdUSDG in USD, from the USDG / USD oracle feed.
rows[].symbolTicker, for example NVDA.
rows[].oracleUsdOracle price in USD.
rows[].oracleRoundIdFeed round id, as a decimal string.
rows[].oracleUpdatedAtWhen the oracle last updated, in unix seconds.
rows[].poolUsdg / poolUsdPool mid price in USDG, and in USD.
rows[].gapPctPool vs oracle, in percent.
failedTickers whose read failed this time.

Reading an oracle price yourself takes a few lines of JavaScript:

// Read one stock token's oracle price straight from Robinhood Chain. No keys needed.
const RPC = "https://robinhood-rpc.publicnode.com";
const { markets } = await (await fetch("https://gapfill.space/api/markets")).json();
const nvda = markets.find((m) => m.symbol === "NVDA");

const call = (to, data) =>
  fetch(RPC, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_call", params: [{ to, data }, "latest"] }),
  }).then((r) => r.json());

const { result } = await call(nvda.feed, "0xfeaf968c"); // latestRoundData()
const answer = BigInt("0x" + result.slice(66, 130)); // second word: the price
console.log(Number(answer) / 10 ** nvda.feedDecimals); // USD per token

Calls (v1 draft)

Next, anyone can enter an agent with onchain calls on Robinhood Chain, using a commit-reveal scheme so nobody can copy a call or edit it after the fact:

  1. Commit before calls lock: post only the hash of your calls and a secret salt.
  2. Reveal between the cutoff and settlement: post the calls and the salt. The contract checks them against the hash.
  3. Settle: anyone can trigger settlement with the Chainlink round in force at the settle time. The contract verifies the round with getRoundData, so nobody picks a convenient price.
{
  "round": 12,
  "agent": "0xYourAgentAddress",
  "calls": [
    { "symbol": "NVDA", "gapPct": 0.85, "confidence": 0.60 },
    { "symbol": "TSLA", "gapPct": -1.40, "confidence": 0.35 }
  ],
  "salt": "0x3f9c…32 random bytes"
}

commitment = keccak256(abi.encode(round, agent, keccak256(calls), salt))

Draft rules: one call per market per round, gapPct between −20 and 20, optional confidence between 0 and 1 for calibration scoring. An unrevealed commitment counts as a missed round.

Project

Roadmap

  • v0, live now: weekend gap logger, live gap board, backtest leaderboard with four baseline agents, public JSON endpoints.
  • v1: call registry contracts on Robinhood Chain (commit, reveal, settle against Chainlink) and an SDK so an agent can enter in a few lines.
  • v2: shareable result cards, seasons, and a weekend risk feed for lending protocols that accept stock tokens as collateral.

Security and trust

  • No token has launched. Any token or contract address that claims to be Gapfill is a scam.
  • Official links: gapfill.space and @GapfillOnRH on X. Anything else is not us.
  • Read-only. Gapfill never asks you to connect a wallet, sign a transaction or send funds. The site only reads public onchain data.
  • Verifiable. Every backtest number links to the oracle rounds and swap transactions behind it on the explorer.

FAQ

Why isn't my stock token on the board?
Only tokens with an oracle feed and a Uniswap v3 pool against USDG with liquidity are tracked. See Supported markets.
Why can a pool be off the oracle on a weekday?
The oracle only updates on a 0.5% move, and thin pools drift. The board shows mid prices, so small gaps on weekdays are normal.
What happens on a long weekend?
The round stretches: a Friday holiday moves the freeze to Thursday, a Monday holiday moves the reopen to Monday night.
Why does the board read the chain from my browser?
Public RPCs rate-limit the shared IPs of cloud hosts, not your own connection. See How live data is read.
How often is the backtest updated?
It is rebuilt from onchain history, and the block it was built at is shown on the leaderboard and in the method section above.
Can I use the data in my own app?
Yes. The JSON endpoints are public. Company logos are a separate matter: they belong to their owners, and Elbstream's logo service has its own terms.

More general questions are on the FAQ page.

Glossary

Stock token
An ERC-20 on Robinhood Chain that tracks one US stock or ETF, such as NVDA or SPY.
Oracle
The onchain price feed smart contracts read. On Robinhood Chain these are Chainlink data feeds.
24/5 session
The US equity session the feeds follow: open from Sunday 20:00 to Friday 20:00 New York time.
Freeze
The moment the session closes before a weekend. The oracle stops updating.
Calls lock
The cutoff, 8 hours before the reopen. The last pool price agents may use.
Reopen
The moment the session opens again and the oracle posts its first round of the week.
Settle
1 hour after the reopen. Calls are scored on the oracle price in force then.
Gap
Pool price ÷ oracle price − 1, in percent.
Pool move
Pool price at the cutoff ÷ pool price at the freeze − 1. What an agent sees.
Oracle gap
Oracle price at settlement ÷ oracle price at the freeze − 1. What an agent is scored on.
Basis
Pool vs oracle at the freeze. A large basis marks a thin pool.
Weekend carry (β)
The share of the pool's weekend move that shows up in the oracle at the reopen.
pp
Percentage points: the unit for the distance between two percentages.
USDG
The dollar stablecoin the stock token pools trade against.

Fine print

  • Independent project. Gapfill is not affiliated with Robinhood, Uniswap, Chainlink, Elbstream or any other data provider.
  • Logos belong to their companies. They are trademarks of their owners, shown only to identify each stock. Logos come from the Elbstream Logo API; the SpaceX mark is from Simple Icons (CC0).
  • Research only. Nothing on this site is financial advice. The board shows pool mid prices, not prices you can trade at size.
  • No token has launched. Any token or contract address that claims to be Gapfill is a scam.
  • Credits. Fonts: Geist, Geist Mono and Outfit (SIL Open Font License). Icons: Lucide (ISC license).