• >OMNICHAIN TVL:
  • >ACTIVE BIOMED NODES:
  • >RENT YIELD INJECTED:
  • >FLOOR RATCHET EVENTS 24H:
  • >HUB BLOCK:
  • >HUB RTT:
  • >ETH USD:$2,700.00 [REFERENCE]
  • >ENV:ROBINHOOD CHAIN MAINNET // HUB LIVE // SPOKES PHASE 2
04 / Smart contract topology

Documentation

The contracts and where they live, the math that makes the floor a one-way ratchet, what a transaction does on the hub, and the APIs researchers and integrators build on.

00 Overview

GridPad is a hub-and-spoke protocol. Every token lives on a master hub on Robinhood Chain, where one invariant engine prices it. The hub is live on Robinhood Chain Mainnet: tokens, trades, ragequits and receiveYield() payments are real transactions, settled in ETH. Four execution spokes, Solana, Base, BNB Chain and Arc, connect over LayerZero V2 in phase 2. Spokes never hold liquidity: they lock funds in escrow and pass signed intents to the hub.

01 Contract index

The GridPad contracts on Robinhood Chain Mainnet and the LayerZero V2 endpoint of every chain in the topology, each checked for deployed code (a check is reused for up to five minutes).

GridPad contracts · Robinhood Chain Mainnet

GridPad contracts on the hub chain
ContractAddressOn-chainSource
GridPadHub · ERC-1967 proxyToken factory, pools, invariant engine, trading, ragequit and receiveYield()0x68B25B61BBAb323F4C022DeaF9a481B19b9Bbf26 checking
GridPadHub · implementation v1.1.0UUPS logic behind the proxy; upgrades are owner-only0x0115FeA73384222ca0a37e9C08A4a57b64075111 checking

Deployed at block 81,879,450 · owner 0xc264cb…537F7f. The owner can upgrade the logic and pause buys and new tokens. The deployed logic has no pause for sells, ragequits or receiveYield(); an upgrade by the owner (one wallet, no timelock) could change that. Each token is a GridPadToken deployed by the hub with CREATE2 (salt keccak256(ticker), init code hash 0x84c3b3e3…f9309c0c); only the hub can mint or burn it.

LayerZero V2 endpoints

LayerZero V2 deployments per chain
ChainChain IDLZ EIDEndpointV2On-chain
Robinhood Chain MainnetMaster hub · live4663304160x6F475642a6e85809B1c36Fa62763669b1b48DD5B checking
SolanaSVM spoke · phase 2n/a3016876y77prsiCMvXMjuoZ5VRrhG5qYBrUMYTE5WgHqgjEn6 checking
BaseEVM spoke · phase 28453301840x1a44076050125825900e736c501f859c50fE728c checking
BNB Smart ChainEVM spoke · phase 256301020x1a44076050125825900e736c501f859c50fE728c checking
ArcEVM spoke · phase 25042304170x6F475642a6e85809B1c36Fa62763669b1b48DD5B checking

Verified live: the API reads each address with eth_getCode (EVM) or getAccountInfo (Solana) on the configured RPC, and source verification from the hub chain's Blockscout explorer, with Sourcify as the fallback.

Token address calculator

A token's address is fixed by its ticker before it exists. Type one to derive it exactly as the hub's CREATE2 does.

Salt · keccak256("FOLD")
0x8211d4bc746953542ae8f3155ab6cdaae080648b3fdd732841a1176faab48982
GridPadToken · Robinhood Chain Mainnet
0x2379295e2e1826C873448a5D259ee837FF267bE9
Status
checking the hub…

02 Deployment record

The hub as it runs on Robinhood Chain Mainnet: the version, every transaction that put it there, and the results of checking it against the live chain at one block. All 20 checks held and all 152 tests passed. The same record is served as JSON, and pnpm hub:check:mainnet runs the checks again; they send no transaction.

Version
v1.1.0verified
Verified at
block 90,882,978 · 2026-10-17 11:14 UTC
Build
solc 0.8.30 · 200 runs · EVM cancun · OpenZeppelin 5.6.1
Runtime code hash
0x553fcc91…203597c3
Live check
reading the proxy…

Transactions

Transactions behind the deployment and the v1.1.0 upgrade
StepBlockTime (UTC)TransactionSent by
Hub implementation v1.0.0 deployedcreated 0xa343…e3815381,879,4502026-10-06 19:310x761206a2…dcebb836deployer0x6eF9…bc39B6
Hub proxy deployed and initialized with the ownercreated 0x68B2…9Bbf2681,879,4782026-10-06 19:310xcbe78e12…9ebb852cdeployer0x6eF9…bc39B6
12 genesis tokens createdwithout an initial buy: FOLD, HELIX, MDYN, STENT, CRISP, ONCO, NEURO, PEPTD, CARDIO, VAXN, TENSR, SYNTH81,879,608–81,880,0752026-10-06 19:32
12 transactions
deployer0x6eF9…bc39B6
Buys paused by the owner82,327,0652026-10-07 08:200xf8f4662f…1f0fe542owner0xc264…537F7f
Hub implementation v1.1.0 publishedcreated 0x0115…07511182,328,2902026-10-07 08:220x2e940481…afa28dccdeployer0x6eF9…bc39B6
Hub upgraded to v1.1.0 by the owner82,337,2212026-10-07 08:370x64a78f53…85afcbfdowner0xc264…537F7f
Buys reopened by the owner82,340,8742026-10-07 08:430x25a05652…7d270812owner0xc264…537F7f

Verification results

Code and source

  • Passed: The implementation is this repository's buildThe runtime code at 0x0115…5111 (17,858 bytes) is GridPadHub compiled from contracts/src with solc 0.8.30, 200 optimizer runs and EVM cancun, byte for byte including its metadata; the one place it may differ, the UUPS immutable (referenced 3 times), holds its own address.
  • Passed: The proxy is OpenZeppelin's ERC1967ProxyThe runtime code at 0x68B2…bf26 is ERC1967Proxy from OpenZeppelin Contracts 5.6.1, as this build compiles it.
  • Passed: Every token is this build's GridPadTokenAll 13 tokens run one runtime code (2,825 bytes): GridPadToken compiled here, with the hub as its immutable.
  • Passed: The sources are verified on SourcifyExact matches, creation and runtime, for the implementation, the proxy, the v1.0.0 implementation it replaced and 12 of the 13 tokens (the other runs the same code).

The live hub

  • Passed: The proxy runs v1.1.0, as the registry recordsThe ERC-1967 implementation slot holds 0x0115…5111 and version() returns 1.1.0, as src/lib/onchain/deployments/mainnet.json records.
  • Passed: Ownership and initializers are as recordedowner() is 0xc264…7F7f, the recorded owner, with no transfer pending; the proxy was initialized once and the implementation's initializers are disabled for good. Buys are open.
  • Passed: Every token sits where its ticker puts itEach of the 13 addresses is the CREATE2 address of the hub, keccak256(ticker) and the recorded init code hash, equals predictTokenAddress(ticker) and tokenOfTicker(ticker), and its token names the hub.
  • Passed: The hub holds exactly its reservesIts balance of 0 ETH equals the sum of every pool's curve and floor reserves; each token's supply equals its pool's, every curve reserve is its exact curve value, and every slope is k₀.

History and the upgrade

  • Passed: Every event since the deployment is accounted for22 hub events from block 81,879,450 to 90,882,978: 13 TokenCreated, 3 Trade, 0 YieldReceived, 2 BuysPaused, 2 Upgraded, 1 OwnershipTransferred, 1 Initialized. Each pool's trade and rent counts, volume and rent total match its on-chain counters, and each token's mints and burns add up to its supply.
  • Passed: The deployment transactions are as recordedThe deployer 0x6eF9…39B6 created the v1.0.0 implementation and the proxy, which was initialized with the recorded owner; it created the 12 genesis tokens without an initial buy, and published v1.1.0 at 0x0115…5111.
  • Passed: The upgrade only switched the implementationTransaction 0x64a7…cbfd from the owner called upgradeToAndCall(0x0115…5111, 0x): no initializer ran, and its only event is Upgraded. Buys were paused at block 82,327,065 and reopened at 82,340,874, both by the owner, with no other hub event in between.
  • Passed: Supplies, balances and token addresses came through the upgrade untouchedNo trade, rent payment or token transfer happened before the upgrade, so every pool and balance stood at zero across it; replaying every event since (3 trades) from there reproduces each pool exactly, and the 12 genesis tokens still sit at the addresses their TokenCreated events gave them, in order.

Exit and redemption on the deployed contract

  • Passed: Every mainnet trade matches the client math to the wei3 trades replayed with src/lib/protocol/hub-math.ts give exactly the tokens, payouts and pool states their Trade events record.
  • Passed: A whole-supply exit on mainnet returned every weiOn 17 October 2026 GCAT's only holder sold all 516,283 tokens for 0.133274 ETH: both reserves, exactly the 0.133274 ETH paid in, and the emptied pool started over at k₀.
  • Passed: On a fork of the live hub, trades and exits pay exactly what the math saysBuys, sells, ragequits and exit() on live pools, among them a guarded buy and a near-sole holder's exit beside a dust holder, match GridPadMath to the wei; a ragequit pays exactly its share of the floor reserve, and the books balance after every step.
  • Passed: The griefing attack fails against the live hubThe slope-inflation sequence that worked on v1.0.0 leaves the slope at k₀ and earns the attacker nothing, and the next buyer is treated as on an untouched pool.
  • Passed: A reverted transaction leaves no partial stateRefused inputs, a burn that fails after the pool is stored, a payout that fails after the burn, and a creation whose first buy fails all leave every pool, supply, balance and storage word as it was.
  • Passed: Exits never pause, and only the owner controls the hubWith buys paused, sells, ragequits, exit() and rent still go through; nobody else can pause, upgrade or take ownership; the bare implementation refuses every call, and reentry is blocked.
  • Passed: The upgrade, replayed with the deployed bytecode, writes only the implementation slotA proxy on the live v1.0.0 implementation, traded on and then upgraded to the live v1.1.0 implementation as on 7 October, keeps every storage word, supply, balance and token address, and trades on under v1.1.0.
  • Passed: 30,720 random calls against the live hub keep every invariantThe invariant campaign on live pools: the floor never falls, the hub's ETH equals its reserves, every curve reserve is exact, the floor stays at least a sixth of spot, supplies match and the slope stays k₀.

Test suites

Test suites run for the record
SuiteResultWhat ran
Foundry: unit, fuzz and invariant testslong profile56 passed8 fuzz tests at 20,000 runs each, and an invariant campaign of 256,000 random calls
Foundry against the live hub (fork)at block 90,882,97815 passedThe deployed bytecode on the live storage, including an invariant campaign of 30,720 calls on live pools
Application tests79 passed · 2 skipped15 files, including the differential test: 160 operations against a local hub (73 buys, 66 of them guarded, 71 exits, 16 rent payments), each matched to the wei. Skipped here: the fork test, which runs on its own at the same block
Differential test against the live hub (fork)at block 90,882,9782 passed160 operations on live pools (74 buys, 66 of them guarded, 71 exits, 15 rent payments), every quote, event and stored pool matched to the wei

A snapshot at block 90,882,978, taken on 2026-10-17 11:14 UTC. The hub is upgradeable by its owner (one wallet, no timelock), so the live check above reads the implementation the proxy runs on every visit.

03 The ratchet math

A token is a linear bonding curve plus a second reserve that only the compute floor can spend. State is four numbers: supply SS, curve reserve RcR_c, floor reserve RfR_f and curve slope kk, which starts at k0=7.5×10−13k_0 = 7.5 \times 10^{-13} ETH per token².

Prices

Pspot=k SP_{\mathrm{spot}} = k\,S
(1)
Spot is linear in supply.
TeX
P_{\mathrm{spot}} = k\,S
Rc=∫0Sk σ dσ=12 k S2R_c = \int_0^{S} k\,\sigma\,\mathrm{d}\sigma = \tfrac{1}{2}\,k\,S^{2}
(2)
The curve reserve is exactly the area under the curve, so every token can always be sold back to it.
TeX
R_c = \int_0^{S} k\,\sigma\,\mathrm{d}\sigma = \tfrac{1}{2}\,k\,S^{2}
Pfloor=RfSP_{\mathrm{floor}} = \frac{R_f}{S}
(3)
The compute floor: each token's exact share of the floor reserve, which is what a ragequit pays.
TeX
P_{\mathrm{floor}} = \frac{R_f}{S}

Buying

xc=34 x,xf=14 xx_c = \tfrac{3}{4}\,x, \qquad x_f = \tfrac{1}{4}\,x
(4)
Every purchase of xx ETH is split exactly: 75% buys on the curve, 25% goes to the floor reserve that collateralises compute hardware.
TeX
x_c = \tfrac{3}{4}\,x, \qquad x_f = \tfrac{1}{4}\,x
12 k[(S+ΔS)2−S2]=xc  ⟹  ΔS=S2+2xc/k − S\tfrac{1}{2}\,k\left[(S+\Delta S)^{2}-S^{2}\right]=x_c \;\Longrightarrow\; \Delta S=\sqrt{S^{2}+2x_c/k}\,-\,S
(5)
Tokens minted, computed on-chain with an integer square root rounded down, so the pool never gives out more than it receives.
TeX
\tfrac{1}{2}\,k\left[(S+\Delta S)^{2}-S^{2}\right]=x_c \;\Longrightarrow\; \Delta S=\sqrt{S^{2}+2x_c/k}\,-\,S
ΔS≤xf SRf  ⟺  xf≥ΔS⋅Pfloor,Rf′=Rf+xf+(Rc+xc−12k(S+ΔS)2)\Delta S \le \frac{x_f\,S}{R_f} \iff x_f \ge \Delta S\cdot P_{\mathrm{floor}}, \qquad R_f' = R_f + x_f + \bigl(R_c + x_c - \tfrac{1}{2}k(S+\Delta S)^{2}\bigr)
(6)
The dilution guard. A buy may never mint more than its floor share can back at the current floor. When it binds, the mint is capped there and the part of the curve share the capped mint does not use goes to the floor reserve, so Rc′=12kS′2R_c' = \tfrac{1}{2}kS'^2 still holds with the same kk: since hub 1.1.0 the slope never changes.
TeX
\Delta S \le \frac{x_f\,S}{R_f} \iff x_f \ge \Delta S\cdot P_{\mathrm{floor}}, \qquad R_f' = R_f + x_f + \bigl(R_c + x_c - \tfrac{1}{2}k(S+\Delta S)^{2}\bigr)
Pfloor′=Rf+xfS+ΔS  ≥  RfS=Pfloor  ⟺  S xf≥Rf ΔSP_{\mathrm{floor}}' = \frac{R_f+x_f}{S+\Delta S} \;\ge\; \frac{R_f}{S} = P_{\mathrm{floor}} \iff S\,x_f \ge R_f\,\Delta S
(7)
Buying never lowers the floor: the right-hand condition is the guard (6) rearranged.
TeX
P_{\mathrm{floor}}' = \frac{R_f+x_f}{S+\Delta S} \;\ge\; \frac{R_f}{S} = P_{\mathrm{floor}} \iff S\,x_f \ge R_f\,\Delta S

Selling and ragequitting

outsell(b)=12 k[S2−(S−b)2]=k b(S−b2),Pfloor′=RfS−b>Pfloor\mathrm{out}_{\mathrm{sell}}(b)=\tfrac{1}{2}\,k\left[S^{2}-(S-b)^{2}\right]=k\,b\left(S-\tfrac{b}{2}\right), \qquad P_{\mathrm{floor}}'=\frac{R_f}{S-b}>P_{\mathrm{floor}}
(8)
A sale is paid from the curve alone. The floor reserve is untouched and now backs fewer tokens.
TeX
\mathrm{out}_{\mathrm{sell}}(b)=\tfrac{1}{2}\,k\left[S^{2}-(S-b)^{2}\right]=k\,b\left(S-\tfrac{b}{2}\right), \qquad P_{\mathrm{floor}}'=\frac{R_f}{S-b}>P_{\mathrm{floor}}
outquit(b)=b Pfloor,Rf′=Rf−b Pfloor+12 k b (2S−b),Pfloor′=Rf′S−b≥Pfloor\mathrm{out}_{\mathrm{quit}}(b)=b\,P_{\mathrm{floor}}, \qquad R_f'=R_f-b\,P_{\mathrm{floor}}+\tfrac{1}{2}\,k\,b\,(2S-b), \qquad P_{\mathrm{floor}}'=\frac{R_f'}{S-b}\ge P_{\mathrm{floor}}
(9)
The ragequit. Burn bb tokens and receive exactly b Pfloorb\,P_{\mathrm{floor}}, with no slippage and no liquidity provider. The burned tokens' curve value stays behind in the floor. The inequality reduces to 12kb(2S−b)≥0\tfrac{1}{2}kb(2S-b)\ge 0. The last holder's exit receives both reserves, so no ETH is ever stranded in an empty pool, and the emptied pool starts over at k0k_0.
TeX
\mathrm{out}_{\mathrm{quit}}(b)=b\,P_{\mathrm{floor}}, \qquad R_f'=R_f-b\,P_{\mathrm{floor}}+\tfrac{1}{2}\,k\,b\,(2S-b), \qquad P_{\mathrm{floor}}'=\frac{R_f'}{S-b}\ge P_{\mathrm{floor}}

Since hub 1.1.0, exit(token, sellAmount, ragequitAmount, minEthOut, deadline) runs (8) and then (9) in one transaction under one minimum. A sale pays the curve's marginal price kSkS, which falls as supply shrinks; a ragequit pays the floor share, which rises. Selling down to where the two meet and burning the rest pays a large holder close to its whole share even when someone else holds a sliver, where selling everything would leave the floor reserve to that sliver. The cockpit's Sell picks this split by itself.

Researcher rent

receiveYield(v):Rf′=Rf+v,Pfloor′=Pfloor+vS,v=upETH\texttt{receiveYield}(v):\quad R_f'=R_f+v, \qquad P_{\mathrm{floor}}'=P_{\mathrm{floor}}+\frac{v}{S}, \qquad v=\frac{u}{p_{\mathrm{ETH}}}
(10)
Rent of uu dollars for the hardware a token's reserve funds is paid as vv ETH at the oracle price pETHp_{\mathrm{ETH}}, straight into its floor reserve in the payment transaction.
TeX
\texttt{receiveYield}(v):\quad R_f'=R_f+v, \qquad P_{\mathrm{floor}}'=P_{\mathrm{floor}}+\frac{v}{S}, \qquad v=\frac{u}{p_{\mathrm{ETH}}}

The two guarantees

t2≥t1  ⟹  Pfloor(t2)≥Pfloor(t1)t_2 \ge t_1 \;\Longrightarrow\; P_{\mathrm{floor}}(t_2) \ge P_{\mathrm{floor}}(t_1)
(11)
The ratchet. By (7), (8), (9) and (10) no operation in the deployed contract can lower the floor. The contract computes in integers (wei, with kk scaled by 103610^{36}), rounds every step in the pool's favour and sweeps the rounding dust into the floor reserve, so the inequalities hold exactly. Foundry invariant tests check them across thousands of random trade sequences.
TeX
t_2 \ge t_1 \;\Longrightarrow\; P_{\mathrm{floor}}(t_2) \ge P_{\mathrm{floor}}(t_1)
Rf≥13Rc  ⟹  Pfloor=RfS≥k S6=Pspot6R_f \ge \tfrac{1}{3}R_c \;\Longrightarrow\; P_{\mathrm{floor}}=\frac{R_f}{S}\ge\frac{k\,S}{6}=\frac{P_{\mathrm{spot}}}{6}
(12)
The floor is never less than a sixth of spot. Buys add xf=13xcx_f = \tfrac{1}{3}x_c to the floor for every xcx_c added to the curve, and sells, ragequits and rent only raise the ratio.
TeX
R_f \ge \tfrac{1}{3}R_c \;\Longrightarrow\; P_{\mathrm{floor}}=\frac{R_f}{S}\ge\frac{k\,S}{6}=\frac{P_{\mathrm{spot}}}{6}

04 Transaction flow

Every action is one transaction on the hub. The interface renders it the moment you sign, then confirms it from the block, then reads the result from the event, with no server in between.

  1. 1Quote

    The interface prices the trade with an exact integer mirror of the contract math, tested against the deployed bytecode to the wei.

  2. 2Simulate

    The call runs as eth_call first, so a revert (slippage, an expired deadline, a paused hub) is explained before you sign or spend gas.

  3. 3Sign

    Your wallet signs the transaction with a minimum out and a deadline.

  4. 4Execute

    The hub splits, mints, burns or pays in one block, about 0.1 s on Robinhood Chain, and enforces the minimum out and the floor ratchet.

  5. 5Emit

    Trade carries the full pool state after the action, YieldReceived the new floor reserve and supply, and TokenCreated the token's name, ticker, manifest and logo.

  6. 6Index

    Charts, floors and balances rebuild from those events alone, in your browser and in the API, within a poll of the block.

Hub interface

solidity · GridPadHub
interface IGridPadHub {
  struct CreateParams {
    string name;          // 2–48 bytes
    string ticker;        // 2–6 of A–Z 0–9, starting with a letter
    uint8 profile;        // 0 biomedical · 1 AI
    uint32[] spokeEids;   // LayerZero EIDs of the spokes (routes open in phase 2)
    bytes32 manifestHash; // keccak256 of the canonical manifest
  }

  function createToken(CreateParams calldata params, bytes calldata logo, uint256 minTokensOut, uint256 deadline)
    external payable returns (address token, uint256 minted);
  function buy(address token, uint256 minTokensOut, uint256 deadline) external payable returns (uint256 minted);
  function sell(address token, uint256 amount, uint256 minEthOut, uint256 deadline) external returns (uint256 ethOut);
  function ragequit(address token, uint256 amount, uint256 minEthOut, uint256 deadline) external returns (uint256 ethOut);
  // Hub 1.1.0: a sale, then a ragequit, in one transaction under one minimum (emits one Trade per leg).
  function exit(address token, uint256 sellAmount, uint256 ragequitAmount, uint256 minEthOut, uint256 deadline)
    external returns (uint256 ethOut);
  function receiveYield(address token, bytes32 ref) external payable;

  event TokenCreated(address indexed token, address indexed creator, bytes32 indexed tickerHash, string ticker,
    string name, uint8 profile, uint32[] spokeEids, bytes32 manifestHash, bytes logo, uint256 timestamp);
  event Trade(address indexed token, address indexed trader, uint8 indexed kind, uint256 ethAmount, uint256 tokenAmount,
    uint256 supply, uint256 curveReserve, uint256 floorReserve, uint256 k, uint256 timestamp);  // kind: 1 buy · 2 sell · 3 ragequit
  event YieldReceived(address indexed token, address indexed from, bytes32 indexed ref, uint256 amount,
    uint256 supply, uint256 floorReserve, uint256 timestamp);
}

Cross-chain intents · phase 2

From phase 2, spokes lock funds in escrow and send intents to the hub over LayerZero V2. The hub executes them in arrival order per token with the same minimum-out and deadline checks, and settles back: minted tokens as OFT transfers, native proceeds through Across on EVM spokes and deBridge on Solana.

solidity · LayerZero packet
payload = abi.encode(uint8 msgType, bytes32 token, bytes32 recipient,
                     uint256 amountIn, uint256 minOut, uint64 deadline, uint64 nonce)
// msgType: 1 buy · 2 sell · 3 ragequit

guid = keccak256(abi.encodePacked(uint64 nonce, uint32 srcEid, bytes32 sender,
                                  uint32 dstEid, bytes32 receiver))
options · spoke → hub · lzReceive 180,000 gas
0x0003010011010000000000000000000000000002bf20
options · hub → Solana · 200,000 CU + 2,500,000 lamports
0x00030100210100000000000000000000000000030d40000000000000000000000000002625a0

05 Token analytics

Every token page reads its economics from the hub contract and lists its history from the hub's own events. The figures are the integers the chain holds (wei, token-wei, and kk scaled by 103610^{36}), every formula is evaluated with the contract's own rounding, and a figure that cannot be read is shown as unavailable rather than estimated.

The economics panel

What the economics panel shows, and where each figure is read from
FigureRead fromShown as
Spot pricegetPool(token).spotPrice: k × S ÷ 10³⁶, rounded downETH per token, with the exact wei
Redemption floorgetPool(token).floorPrice: floor reserve × 10¹⁸ ÷ circulating supply, rounded downETH per token, with the exact wei; undefined while nothing is in circulation
Floor reservegetPool(token).floorReserveETH, with the exact wei
Circulating supplytotalSupply() of the token contracttokens, to the last of their 18 decimals
Network and blockthe block the read was pinned to, and its headerthe chain, the block number with an explorer link, and its time in UTC
Contractsthe deployment record, and the proxy’s ERC-1967 slot at that blocklinks to the token, the hub, the implementation it ran and its verified source
Pfloor=⌊Rf⋅1018S⌋ wei per token,S=totalSupply()P_{\mathrm{floor}} = \left\lfloor \frac{R_f \cdot 10^{18}}{S} \right\rfloor \ \text{wei per token}, \qquad S = \texttt{totalSupply()}
The redemption floor, as floorPrice() computes it: the floor reserve over the circulating supply, rounded down to the wei. The panel works it on the RfR_f and SS it shows and sets the result beside the contract's own value at the same block. With S=0S = 0 nothing is in circulation and the floor is undefined.
TeX
P_{\mathrm{floor}} = \left\lfloor \frac{R_f \cdot 10^{18}}{S} \right\rfloor \ \text{wei per token}, \qquad S = \texttt{totalSupply()}

One eth_call through Multicall3, pinned to the block the page's event index has reached, returns the pool, the token's totalSupply(), the hub's balance, every pool's reserves and the hub's version; the block header and the proxy's implementation slot come in the same JSON-RPC batch. The read goes through the browser's own connection to Robinhood Chain Mainnet, not through GridPad's server, and repeats after every event for the token, every 30 seconds and on request.

The checks

  • Floor = floor reserve ÷ circulating supplyThe formula worked on the two inputs the panel shows equals floorPrice() to the wei.
  • Spot = k × supply ÷ 10³⁶spotPrice() equals the formula on the pool’s slope and supply.
  • Circulating supply = the hub’s supplyThe token contract’s totalSupply() equals the supply the pool accounts for: only the hub mints and burns.
  • Curve reserve = ½ · k · S²The curve reserve equals curveValue(S, k), so the curve can buy back every token in circulation.
  • The hub holds every reserveThe hub’s ETH balance covers the curve and floor reserves of every pool on the hub, read at the same block.
  • The verified implementationThe proxy ran the implementation phase 1.2 verified against the live hub (where there is no verification, the one the deployment record names).
  • The event index agreesReplaying the hub’s events up to the block gives the contract’s supply, reserves, slope, trade and rent counts, volume and rent total.

States

The economics panel's states
StateWhen
verifiedEvery check that could be made passed, and the read is current.
updatingThe token changed after the read. A new read is under way; until it lands the last figures stay, set back.
reconcilingOnly the event index disagrees, which an RPC node a few blocks behind causes for a poll or two. The panel reads again within seconds.
staleThe last read that succeeded is more than 90 seconds old, or the token changed after it and the next read failed. The figures shown are the last confirmed ones.
inconsistentA check failed, and the panel names it. For the event index, only once the difference has lasted 3 reads and 10 seconds.
unavailableNo read has succeeded. No figures are shown, not even an estimate.

Dollar figures appear only beside a live ETH/USD quote, marked as reference: the contract prices in ETH. The cockpit's header keeps to the same rule. Without a live quote it shows a dash with the ETH figure beside it, never a reference price, and its line above the panels says whether the event index is live and which block it has reached.

Activity history

Below the panels, every hub event for the token, newest first and 25 at a time: TokenCreated, Trade (a buy, a sell or a ragequit) and YieldReceived (rent). Each entry has its time, its kind, the wallet, the ETH and tokens it moved, the floor after it, and links to its block and transaction on the explorer; a creation's first buy and the two legs of an exit() are marked as such. The entries come from the page's event index, which the browser builds from the hub's logs. A transaction still waiting for its block is not an entry: it stays under Your transactions until its event arrives. When the index stops updating, the history says from which block on events may be missing.

The API serves both from its own index: /api/v1/tokens/{ticker}/economics reads the contract at the block the server's index has reached and returns the figures with their checks, and /api/v1/tokens/{ticker}/activity pages through the history with a cursor (Integration APIs).

06 Integration APIs

JSON over HTTPS, no key required, served from GridPad's own index of the hub's events and, for a token's economics, from the contract itself. Errors use one shape, { "error": { "status", "message" } }. Lease and job tickets are HMAC-signed by the server and act as bearer tokens, so the API keeps no session state. Write endpoints are rate limited per client address (an IPv6 /64 counts as one): 40 image lookups, 20 leases and 20 jobs per minute, on a best-effort basis per server instance.

Paying for a lease · phase 3

The rent is the payment and the proof. Pay receiveYield(token, ref) on the hub with a reference that commits to the terms; the API reads the transaction's YieldReceived event and opens exactly the lease it paid for. Changing any term changes the reference, and the claim fails. Paid leasing opens in phase 3, when real nodes run the jobs. Until then the lease and job endpoints answer 503, so do not pay rent expecting a lease. The flow below is the integration it will use.

typescript · viem
import { createPublicClient, createWalletClient, custom, encodeAbiParameters, http, keccak256 } from 'viem'
import { robinhood } from 'viem/chains'

const hub = '0x68B25B61BBAb323F4C022DeaF9a481B19b9Bbf26'
const wallet = createWalletClient({ chain: robinhood, transport: custom(window.ethereum) })
const client = createPublicClient({ chain: robinhood, transport: http() })
const [payer] = await wallet.requestAddresses()

// 1. Terms and price: rate × nodes × hours, in ETH at the oracle price.
const terms = { payer, token: '0x…', ticker: 'FOLD', tier: 'a100_80', cluster: 'sin-02', nodes: 1, hours: 6, nonce: 7n }
const { prices } = await (await fetch('/api/v1/prices')).json()
const usd = 1.6 * terms.nodes * terms.hours
const value = BigInt(Math.ceil((usd / prices.ETH) * 1e18))

// 2. The reference commits the payment to exactly these terms.
const ref = keccak256(encodeAbiParameters(
  [{ type: 'string' }, { type: 'uint256' }, { type: 'address' }, { type: 'address' }, { type: 'address' },
   { type: 'string' }, { type: 'string' }, { type: 'string' }, { type: 'uint16' }, { type: 'uint16' }, { type: 'uint64' }],
  ['GRIDPAD_LEASE_V1', 4663n, hub, terms.payer, terms.token, terms.ticker, terms.tier, terms.cluster,
   terms.nodes, terms.hours, terms.nonce],
))

// 3. Pay the rent: it lands in the token's floor reserve in this transaction.
const tx = await wallet.writeContract({
  address: hub, account: payer, value,
  abi: [{ type: 'function', name: 'receiveYield', stateMutability: 'payable', outputs: [],
          inputs: [{ name: 'token', type: 'address' }, { name: 'ref', type: 'bytes32' }] }],
  functionName: 'receiveYield', args: [terms.token, ref],
})
await client.waitForTransactionReceipt({ hash: tx })

// 4. Claim the lease: the API checks the YieldReceived event and returns a ticket that authorises jobs.
const res = await fetch('/api/v1/compute/leases', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ tx, terms: { ...terms, nonce: terms.nonce.toString() } }),
})
const { lease, ticket } = await res.json()

Endpoints

GET/api/v1/status

Hub chain height and RPC latency measured on request, the deployment, the server index and the oracle quote.

curl
curl 'https://gridpad.network/api/v1/status'
GET/api/v1/tokens

Tokens on the hub in creation order: spot, floor, reserves (exact wei and rounded), 24h activity, funded compute and rent received. Paged; total counts every token.

limit
1 to 500 tokens per page (default 100)
offset
tokens to skip (default 0)
curl
curl 'https://gridpad.network/api/v1/tokens'
GET/api/v1/tokens/{ticker}

One token with its contract, creator, manifest, registered spokes and the clusters its floor funds.

curl
curl 'https://gridpad.network/api/v1/tokens/FOLD'
GET/api/v1/tokens/{ticker}/candles

OHLC from the hub’s trades, with the floor and the rent-funded floor per bucket.

interval
60, 300, 900, 3600, 14400 or 86400 seconds (default 300)
count
1 to 1000 buckets (default 288)
unit
eth (default) or usd, converted at the current ETH price
curl
curl 'https://gridpad.network/api/v1/tokens/FOLD/candles?interval=900&count=4'
GET/api/v1/tokens/{ticker}/floor

The floor, recent receiveYield() payments, and the exact ragequit payout for the current block.

amount
tokens to quote a ragequit for, as a decimal string, up to the supply (optional)
curl
curl 'https://gridpad.network/api/v1/tokens/FOLD/floor'
GET/api/v1/tokens/{ticker}/economics

The token’s economics read from the hub contract at the block the server’s index has reached: spot, the redemption floor (floor reserve ÷ circulating supply, per token), the floor and curve reserves, the circulating supply (totalSupply()), the hub’s balance against every reserve and the implementation the proxy ran, as exact integers with exact decimals, and the seven checks that reconcile them. usd is null without a live quote; 503 when the contract cannot be read.

curl
curl 'https://gridpad.network/api/v1/tokens/FOLD/economics'
GET/api/v1/tokens/{ticker}/activity

The token’s activity history, newest first: one entry per hub event (TokenCreated, Trade, YieldReceived) with its transaction, block, wallet, exact amounts, the pool after it and explorer links. Entry ids are the chain positions the stream uses for its event ids.

limit
1 to 100 entries per page (default 25)
before
the previous page’s next, or an entry id: only older entries
type
created, buy, sell, ragequit or rent, comma-separated (optional)
curl
curl 'https://gridpad.network/api/v1/tokens/FOLD/activity?limit=5'
GET/api/v1/prices

USD prices for ETH, SOL, BNB and USDC: Pyth when keyed, otherwise Coinbase, then Kraken.

curl
curl 'https://gridpad.network/api/v1/prices'
GET/api/v1/contracts

The hub contracts and the LayerZero endpoint on every chain, checked for deployed code (results kept up to five minutes), with explorer source verification.

curl
curl 'https://gridpad.network/api/v1/contracts'
GET/api/v1/deployment

The deployment record: the registry the app runs on (addresses, every implementation the hub has run, the transactions behind them), the verification of the live hub with its checks, transactions, replayed trades and test suites, and the implementation the proxy runs now.

curl
curl 'https://gridpad.network/api/v1/deployment'
GET/api/v1/compute/clusters

Akash and io.net clusters with the nodes token floors fund in each, idle capacity and rates.

curl
curl 'https://gridpad.network/api/v1/compute/clusters'
GET/api/v1/compute/images

Resolve a public container image on its registry (Docker Hub, GHCR, Quay, NGC, ECR Public, GitLab, MCR): digest, platforms, layers, size.

ref
image reference, e.g. gromacs/gromacs:latest
curl
curl 'https://gridpad.network/api/v1/compute/images?ref=python:3.12-slim'
POST/api/v1/compute/leases

Open a lease from its on-chain rent payment. The API rebuilds the reference from the terms and checks the YieldReceived event: payer, token, amount at the oracle price. Idempotent. Opens with paid leasing in phase 3; until then it answers 503.

request
curl -X POST 'https://gridpad.network/api/v1/compute/leases' \
  -H 'content-type: application/json' \
  -d '{"tx":"0x…","terms":{"payer":"0x…","token":"0x…","ticker":"FOLD","tier":"a100_80","cluster":"sin-02","nodes":1,"hours":6,"nonce":"7"}}'
POST/api/v1/compute/jobs

Run a container on a lease. The image is resolved on its registry before the job is accepted; the response carries a job ticket. Opens with paid leasing in phase 3; until then it answers 503.

request
curl -X POST 'https://gridpad.network/api/v1/compute/jobs' \
  -H 'content-type: application/json' \
  -d '{"ticket":"<lease ticket>","image":"gromacs/gromacs:latest","command":"gmx mdrun -deffnm npt","env":{"OMP_NUM_THREADS":"64"}}'
GET/api/v1/compute/jobs/{id}

Job phase, progress, node, artifact and logs. Opens with paid leasing in phase 3; until then it answers 503.

header
Authorization: Bearer <job ticket>
since
unix seconds: return only newer log lines
curl
curl 'https://gridpad.network/api/v1/compute/jobs/JB-…' \
  -H 'Authorization: Bearer <job ticket>'
SSE/api/v1/stream

Server-Sent Events as blocks are mined: created, trade and yield events with the state after each, and a tick with the block height. Event ids are chain positions, as in the activity history: a reconnecting EventSource sends Last-Event-ID and first receives what it missed (the last 1,000 events at most).

ticker
only this token (optional)
since
resume after this block (optional; Last-Event-ID does the same)
curl
curl -N 'https://gridpad.network/api/v1/stream?ticker=FOLD'
opens a live EventSource from this page

07 Mainnet scope

This deployment runs on Robinhood Chain Mainnet: every token, trade, ragequit and floor is real ETH, settled by the hub contract. The contracts have not had a security audit yet. What is live, what is simulated, and the road from here:

live · mainnet
  • The hub contract, every token, trade, ragequit and floor, in ETH
  • receiveYield(): anyone can pay into a token's floor, which only ever rises
  • Prices, charts and balances, rebuilt from hub events
  • Exact quotes from an integer mirror tested against the contract
  • Each token's economics read from the contract at a pinned block and reconciled with the chain, and its history of hub events
  • Owner controls: pausing buys and new tokens, and upgrades. The deployed contract has no pause for sells, ragequits or receiveYield(); the hub is upgradeable, and its owner (one wallet, no timelock) could replace that logic
  • LayerZero endpoints and source verification, checked on request and kept up to five minutes
  • ETH prices from Pyth, Coinbase or Kraken; container images resolved on their registries
simulated · until phase 3
  • Node counts follow the live floor reserves at full collateral ($7,000 per HM-512 node); no hardware is provisioned yet
  • Node utilisation and the hardware telemetry feed
  • Compute leases and job execution: paid leasing opens with real nodes, and the portal takes no rent until then

The twelve genesis tokens were created by GridPad's deployer without an initial buy, so the first trader opens each curve; only tokens that account created carry the Genesis badge. Mainnet has no seeded trading history: what the board and the charts show is what traders have done.

Roadmap

Two milestones come before phase 2: 1.2 verified the hardened hub where it runs and published its deployment record, and 1.3 made each token's economics and activity inspectable from contract data. Both reuse what is live, with no new chains, contracts or tokenomics, before omnichain work adds its cost and complexity. A status changes, and a criterion is ticked, only once the work is built, tested and verified on the network it runs on; dates mark only what has happened.

  1. Phase 1: Mainnet hub

    live

    The hub and twelve genesis tokens on Robinhood Chain Mainnet, with the board, cockpit, launcher, docs and API.

    Live since 6 October 2026 (block 81,879,450). The first trades came on 16 October 2026 (block 90,475,518).

    Scope
    • The hub contract and its twelve genesis tokens
    • Board, cockpit, token launcher, docs and the public API
    • Leases closed until phase 3
    Done when
    • Met: First trades on mainnet
    • Open: Uptime, with no incident

    Depends on phase 0, the testnet · Hub proxy ↗ · Contract index

  2. Phase 1.1: Hardening

    complete

    Upgrade the hub to v1.1.0, with its security and exit improvements.

    Upgraded on 7 October 2026: the proxy has run v1.1.0 since block 82,337,221, and buys reopened the same day. The site moved to gridpad.network on 14 October.

    Scope
    • The fix for the empty-pool griefing vector: the slope never moves, a guarded buy sweeps its unused curve share into the floor, and an emptied pool restarts at k₀
    • exit(): the optimal way out, a sale then a ragequit in one transaction under one minimum
    • onlyProxy on every state-changing entry point
    • Documentation on the v1.1.0 math, and the gridpad.network domain
    Done when
    • Met: The proxy runs v1.1.0
    • Met: The deployment record is updated
    • Met: Buys reopened

    Depends on phase 1, and the owner's signature · Upgrade transaction (block 82,337,221) ↗ · Implementation v1.1.0 ↗ · Buys reopened ↗

  3. Phase 1.2: Protocol hardening and exit improvements

    complete

    Verify and deploy the existing protocol hardening work, validate exit and redemption behavior, and publish the resulting deployment record.

    Verified on 17 October 2026 against the live hub at block 90,882,978: the running code is this repository's build, the upgrade left every supply, balance and token address untouched, all 3 mainnet trades match the client math to the wei, and all 20 checks and 152 tests passed, among them the suites run on a fork of the deployed contract. The deployment record publishes the version, the transactions and the results.

    Scope
    • Verify the griefing fix, the optimal exit, floor redemption and reserve accounting on the live hub
    • Confirm that buys, sells and ragequits behave as before, that a reverted transaction leaves no partial state, and that the upgrade left supplies, balances and token addresses untouched
    • Re-run the Foundry unit, fuzz and invariant tests, the app tests and the exact contract/client math comparison, adding regression tests for any gap
    • Publish the deployment record: the version, its transactions and the verification results
    Done when
    • Met: v1.1.0 is the active implementation on Robinhood Chain Mainnet
    • Met: The deployment registry and the docs match the chain
    • Met: Security and regression tests pass against the deployed implementation
    • Met: Exit and redemption are verified against the deployed contract
    • Met: A deployment record with the version, the transactions and the verification results is published

    Depends on phase 1.1 · Deployment record · Contract index

  4. Phase 1.3: On-chain transparency and token analytics

    complete

    Improve visibility into token economics and on-chain activity using verified contract data, transaction history, and the existing API.

    Released on 17 October 2026. Every token page reads its spot price, redemption floor, floor reserve and circulating supply from the hub contract at a pinned block, works the floor formula on them, reconciles them with the chain and the event index, and lists the token’s hub events with their transactions. Checked against the live hub at block 91,292,202: all 91 checks held for its 13 tokens, and all 16 of its events were found in their transactions’ receipts.

    Scope
    • An economics panel on each token page: spot price, the redemption floor (floor reserve ÷ circulating supply, in ETH), the floor reserve, the circulating supply, the network, the block it was read at, and contract links
    • An activity history from the hub's own events (creation, buys, sells, ragequits and rent), each entry with its transaction, block, wallet, amounts and explorer link, loaded page by page
    • Exact integer math for authoritative values, and an explicit stale or unavailable state instead of a guessed number
    • Built on the existing cockpit, indexer, event stream and API: no new contracts, chains or database
    Done when
    • Met: Token pages show the verified economic metrics the contract supports
    • Met: The floor formula and its displayed inputs reconcile with on-chain state
    • Met: Every activity entry comes from a real hub event and links to its transaction
    • Met: Stale, missing and inconsistent data is shown as such
    • Met: Trading and token creation work as before
    • Met: The API and UI documentation are updated
    • Met: Automated tests cover data integrity and rendering

    Depends on phase 1.2, whose verified contract it reads; it ships as a separate release · Token analytics · Integration APIs

  5. Phase 2: Omnichain

    designed

    Extend token execution to Solana, Base, BNB Chain, and Arc through the planned cross-chain architecture.

    The packet payloads and executor options are specified; no spoke is deployed and no route is open.

    Scope
    • Spoke escrows on Solana, Base, BNB Chain and Arc
    • LayerZero V2 intents, the hub lockbox and OFTs
    • Proceeds through Across and deBridge; rent in dollars
    Done when
    • Open: Buys, sells and ragequits from every spoke settle within the latency budget, with refunds on rejection
    • Open: An external review of the new contracts

    Depends on phases 1.2 and 1.3 · Transaction flow

  6. Phase 3: Compute

    designed

    Real compute provisioning, paid leases, and rent landing in the floors.

    Until then node counts, utilisation and telemetry are simulated on mainnet, and the lease endpoints take no rent.

    Scope
    • The compute adapter on Akash and io.net
    • The funding model
    • Paid leases on mainnet, compute receipts and real telemetry
    Done when
    • Open: Paying labs
    • Open: Rent landing in floors from real jobs
    • Open: Published receipts, with measured margin and utilisation

    Depends on a decision on the funding model, and real nodes on Akash and io.net

  7. Phase 4: Durability

    proposed

    An external audit, upgrade governance and a funded operating plan.

    Scope
    • External audit
    • Upgrade governance
    • A sustainability decision: protocol revenue or none
    • Secondary-market integrations and research partnerships
    Done when
    • Open: An audit report is published
    • Open: Governance is in place
    • Open: A funded operating plan

    Depends on decisions on the audit, upgrade governance and protocol revenue