gitstock
tokens / SPY

SPYETF

SPDR S&P 500 ETF Trust • Robinhood Token

$760.04
live · feed 15h ago
Contract
0x117cc2133c37B721F49dE2A7a74833232B3B4C0C explorer ↗
Price feed
0x319724394D3A0e3669269846abE664Cd621f9f6A explorer ↗ · +1 alt proxy
Holders
not yet indexed
Pool TVL
$3,112,589 across 29 pools · main WETH/SPY (v3)
Dependents
PIGGY (v2) RVH (v3) CASHCAT (v3) Andy (v3) HOODIE (v3) Analyst (v3) VLAD (v3) world (v3) Emilio (v3) ARROW (v3) WOLF (v3) ZA (v3) +177 more →
Multiplier
1.000000 (uiMultiplier · price = stock × this)
✓ Canonical · factory-verified✓ Chainlink feed · proxy confirmedTVL $3,112,589

Price

Not enough history yet — the chart draws once a full day of prices is indexed.

Pools

PoolPairDEXTVL
0xDDCBBa36…59AB5eWETH/SPYv3$1,760,235
0x38453c11…f3Df4EUSDG/SPYv3$468,018
0xa7Bb1AC6…689167USDG/SPYv3$284,128
0x47A2a145…eAF90bUSDG/SPYv3$255,876
0x3e1afDe9…008c7EWETH/SPYv3$216,553
0xaBE817Af…EaaeAEUSDG/SPYv3$39,515
0xd89cAc2d…c9DAEFUSDG/SPYv3$31,541
0xA43b424B…0B0aD9USDG/SPYv3$25,785
0x851C08d1…900F34WETH/SPYv2$15,588
0xb236e833…C2Dd86USDG/SPYv2$15,311
0x7A726F6e…5aC698USDG/SPYv3$20
0x75261396…02ef84USDG/SPYv3$18

+16 more pools with dust liquidity (<$1).

README

SPY is the Robinhood Chain token wrapping the SPDR S&P 500 ETF Trust — a broad-market index in one token. BeaconProxy (ERC-20, 18 decimals) on the shared Stock implementation.

Priced by the Chainlink feed “RHSPY / USD”. Because it's a total-return token, distributions reinvest through uiMultiplier(), so it drifts above the headline ETF quote. Third-party tokens paired against it on-chain are tracked under Dependents.

Integrated SPY? Hit a quirk these notes miss?Add a field note →

Read the price

// Read SPY correctly on Robinhood Chain (chain 4663). ethers v6.import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider(RPC);
const feed = new ethers.Contract(
  "0x319724394D3A0e3669269846abE664Cd621f9f6A",
  ["function latestRoundData() view returns (uint80,int256,uint256,uint256,uint80)",
   "function decimals() view returns (uint8)"],
  provider
);

// price = stock × uiMultiplier already — do NOT multiply again
const dec = await feed.decimals();
const rd  = await feed.latestRoundData();
const priceUSD = Number(ethers.formatUnits(rd.answer, dec));

// the real guard: 24h heartbeat (feeds are 24/5)
const now = (await provider.getBlock("latest")).timestamp;
const stale = Number(now) - Number(rd.updatedAt) > 86400;
// NOTE: do NOT gate on the L2 sequencer feed — it's hardwired to 'down' here.

Or just fetch the record

No RPC, no ABIs, no guard logic — gitstock already resolved and guarded everything.

// No RPC or ABIs needed — fetch the whole resolved record.
const r = await fetch("https://gitstock.io/SPY/stock.json");
const s = await r.json();

s.price.usd     // live price (already stock × multiplier)
s.holders       // holder count
s.tvlUsd        // pool TVL in USD
s.dependents    // tokens paired against SPY
s.feed.proxy    // the Chainlink proxy gitstock reads
s.fieldNotes     // the quirks that break integrations

Field notes — what the docs don't tell you

SPY has a primary and a secondary feed proxy

Chainlink registers two proxies for this feed, both resolving to the same aggregator with identical data. gitstock publishes Chainlink's canonical primary (proxyAddress) as feedProxy and keeps the secondary under feedProxyAlt. Either reads correctly — use the primary.

The price feed is not on the token

The Stock token carries no price and no feed pointer on-chain — no latestRoundData(), no priceFeed(). The Chainlink feed is a separate, unlinked contract, and the token→feed mapping isn't published anywhere. gitstock resolves it for you (verified via the token factory's own creation events, not by symbol).

The L2 sequencer gate is hardwired to “down”

Robinhood ships a custom SequencerGate whose source() is currently the zero address — so latestRoundData() returns answer = 1 (down) forever, while the price feeds are healthy. Copy the standard Chainlink pattern require(sequencerUp == 0) and your app will never render a price here. Read the gate for transparency, but don't hard-gate on it yet.

Staleness is the real guard — heartbeat is 24h

Because the sequencer gate is unusable, freshness on the feed itself is the actual safety check. The official heartbeat is 86400s: feeds publish at least daily and more often on deviation (~17min–1h in US market hours, hours apart overnight; 24/5). Only treat a price as stale once now − updatedAt > 86400 — anything tighter false-flags overnight and weekend reads.

Feed price is the TOKEN price, not the stock price

latestRoundData() already returns stock_price × uiMultiplier() — don't apply the multiplier again. Dividends reinvest through the multiplier, so the token tracks total return and drifts above the headline stock price over time. That's why the number here won't match Google Finance.

oraclePaused() is advisory, not enforced

During corporate actions the token oracle is paused. oraclePaused() == true means “price temporarily unavailable”, not zero/error — and it isn't enforced on-chain, so a paused oracle can still return a value. Treat it as a display state; rely on staleness for protection.

Read decimals() on-chain; don't hardcode

Feed answers use the feed's own decimals (8 for these USD feeds). Read decimals() from the proxy every time rather than assuming.

Community notes

No community notes yet — be the first.

SPY/stock.json — machine-readable record · SPY/history.json — indexed price series · SPY/badge.svg — README badge