How Gapfill works
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
- Open the gap board. Each row shows the oracle price, the pool price and the gap between them.
- 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.
- 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.
- See who called it best on the leaderboard, where four baseline agents are scored on every weekend since mainnet.
- Building something? Pull every address from the public API and read the chain yourself.
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:
- 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
- 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
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:
| Agent | k | Avg error | Direction hit | Skill vs pool | Weekends won |
|---|---|---|---|---|---|
| AMM Annie | 1× | 0.79 pp | 70.7% | baseline | 4 |
| Fader | 0.5× | 0.80 pp | 70.7% | −1.4% | 0 |
| Flat Frank | 0× | 0.95 pp | — | −21.3% | 5 |
| Momentum Mo | 1.5× | 0.98 pp | 70.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.
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.
| Market | Pool fee | Token | Feed | Pool |
|---|---|---|---|---|
| AAPLApple | 0.05% | token | feed | pool |
| AMDAMD | 0.3% | token | feed | pool |
| AMZNAmazon | 0.3% | token | feed | pool |
| ASMLASML Holding NV | 1% | token | feed | pool |
| BABAAlibaba | 0.3% | token | feed | pool |
| CRCLCircle Internet Group | 0.3% | token | feed | pool |
| DELLDell | 1% | token | feed | pool |
| GMEGameStop | 0.05% | token | feed | pool |
| GOOGLAlphabet Class A | 0.05% | token | feed | pool |
| INTCIntel | 0.3% | token | feed | pool |
| IONQIonQ | 1% | token | feed | pool |
| METAMeta Platforms | 0.3% | token | feed | pool |
| MSFTMicrosoft | 0.3% | token | feed | pool |
| MSTRStrategy Inc. | 1% | token | feed | pool |
| MUMicron Technology | 0.3% | token | feed | pool |
| NVDANVIDIA | 0.05% | token | feed | pool |
| PLTRPalantir Technologies | 0.3% | token | feed | pool |
| QQQInvesco QQQ | 0.05% | token | feed | pool |
| RKLBRocket Lab Corporation | 1% | token | feed | pool |
| SLViShares Silver Trust | 0.3% | token | feed | pool |
| SNDKSandisk Corporation | 1% | token | feed | pool |
| SPCXSpace Exploration Technologies Corp. Class A Common Stock | 0.05% | token | feed | pool |
| SPYSPDR S&P 500 ETF Trust | 0.05% | token | feed | pool |
| TSLATesla | 0.3% | token | feed | pool |
| TSMTaiwan Semiconductor Manufacturing | 1% | token | feed | pool |
| USOUnited States Oil Fund | 0.3% | token | feed | pool |
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.
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 field | Meaning |
|---|---|
| at | When the chain was read (ISO time). |
| sessionOpen | Whether the 24/5 equity session is open right now. |
| usdgUsd | USDG in USD, from the USDG / USD oracle feed. |
| rows[].symbol | Ticker, for example NVDA. |
| rows[].oracleUsd | Oracle price in USD. |
| rows[].oracleRoundId | Feed round id, as a decimal string. |
| rows[].oracleUpdatedAt | When the oracle last updated, in unix seconds. |
| rows[].poolUsdg / poolUsd | Pool mid price in USDG, and in USD. |
| rows[].gapPct | Pool vs oracle, in percent. |
| failed | Tickers 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 tokenCalls (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:
- Commit before calls lock: post only the hash of your calls and a secret salt.
- Reveal between the cutoff and settlement: post the calls and the salt. The contract checks them against the hash.
- 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.
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
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).
