Skip to console
SAND
𝕏

INSTRUCTION BOOKLET · KEEP FOR REFERENCE

SAND MANUAL

SECTION 01

START

Power on. The console boots SAND OS, checks the channel (chain id 4663) and prints the current head. Pick a cart from the menu with ↑↓ and press A. Paste a cartridge, press START (or BOOT) to read it.

A = select / save slot · B = back · START = boot / re-read · SELECT = READOUT ⇄ RAW · RH = channel details · ←→ = tabs · ↑↓ = scroll

The boot animation can be skipped after your first visit; the preference is stored locally. Motion is disabled entirely when your system asks for reduced motion.

SECTION 02

CARTRIDGES

SAND detects the cartridge type from what you paste:

  • 0x + 64 hex characters → TRACE (transaction)
  • 0x + 40 hex characters → address; bytecode decides WALLET vs CONTRACT, and ERC-20 / pool probes decide TOKEN or POOL
  • digits, or "latest" → BLOCK
  • an explorer URL → the identifier inside it

An address is never called a token because it looks like one. It is a token when totalSupply(), decimals(), balanceOf() and allowance() return well-formed words and the bytecode dispatcher carries the core ERC-20 selectors.

SECTION 03

TOKEN CART

Reads name(), symbol(), decimals() and totalSupply() by eth_call, all pinned to one block. Adds bytecode size, the contract's own ETH balance, the EIP-1967 proxy slot, and Blockscout verification when the indexer answers.

MARKET tab: the deepest pool located across the registered V2 and V3 factories (price, depth), every other pool that answered, indexed holders, indexed activity counters and the SAND SCORE. Pool price, liquidity and the fully-diluted market cap are printed only when a real pool was read; otherwise they say NOT AVAILABLE.

The explorer's own market figures (USD price, 24h volume, circulating market cap) are shown as separate rows labelled INDEXER. They come from Blockscout's market data, never from a pool read, and they never feed the SAND SCORE. Activity uses the token's lifetime transfer counter from the explorer.

With a controller connected, YOUR BALANCE is read from balanceOf(your address).

SECTION 04

WALLET CART

ETH balance (eth_getBalance), nonce (eth_getTransactionCount), type (bytecode is 0x) and the block the reads were pinned to. Transaction history is INDEXER DATA from Blockscout, first page only; the RPC alone cannot list transactions by address, and SAND says so on the screen.

TOKENS tab: ERC-20 holdings listed by the indexer, then the top eight re-read with balanceOf(wallet) at the pinned block. A ✓ means the contract and the indexer agree; a ≠ prints both values.

SECTION 05

TRACE CART

eth_getTransactionByHash + eth_getTransactionReceipt. Fee = gasUsed × effectiveGasPrice and is labelled CALCULATED. The method selector is matched against a small local table of common signatures; a match is labelled, a miss stays UNDECODED.

Events are decoded in two labelled layers. First, SAND's fixed ABI of standard events (ERC-20/721/1155 Transfer and Approval, ERC-1155 TransferSingle/Batch, UniswapV2 Swap/Sync/Mint/Burn, WETH Deposit/Withdrawal). Then, for logs that layer could not read, the explorer's decoding from the emitter's verified ABI or signature database, tagged INDEXER. The method name and decoded input parameters use the same explorer source when the target contract is verified. Anything still unknown prints its raw topics and data. SAND never invents an ABI.

SECTION 06

POOL CART

Pools are read only from registered factories (SUPPORTED_POOLS). For a token, SAND calls getPair(token, quote) on each registered Uniswap V2-compatible factory for each quote asset, verifies the pair has bytecode, then reads token0(), token1(), getReserves() and totalSupply() at one block.

price = reserve_quote × 10^dec_base ÷ (reserve_base × 10^dec_quote)

Uniswap V3-compatible factories use getPool(token, quote, fee) for the 0.05% / 0.3% / 1% tiers and read slot0(), liquidity() and fee(). Price comes from sqrtPriceX96. V3 depth is the pool contract's real token balances (balanceOf(pool) on both sides); the in-range virtual reserve is shown in the STATE tab as a labelled estimate. The registered V3 factory is the verified Robinhood Chain UniswapV3Factory 0x1f7d…2efa, checked on-chain before registration.

When several pools answer, the deepest one (quote-side depth, in USDG where a reference exists) is priced and the others are listed under OTHER POOLS.

WETH-quoted values get a USDG reference (price × WETH/USDG from the same factory at the same block). USDG is a stablecoin, so the label is USDG, never USD.

SECTION 07

SAND SCORE

Deterministic, never model-generated. Weights: LIQUIDITY 30, DISTRIBUTION 25, ACTIVITY 20, CONTRACT 15, FRESHNESS 10. Signals that cannot be measured are removed from the available weight instead of scoring zero:

FINAL = earned ÷ available × 100

LIQUIDITY (30)

pool in a registered factory → 10 pts

quote depth in USDG:

  • 100,000 USDG15 pts
  • 10,000 USDG11 pts
  • 1,000 USDG7 pts
  • 100 USDG3 pts
  • otherwise → 0 pts

quote depth in WETH (no USDG reference):

  • 50 WETH15 pts
  • 5 WETH11 pts
  • 0.5 WETH7 pts
  • 0.05 WETH3 pts
  • otherwise → 0 pts

reserves read ≤ 20 blocks behind head → 5 pts

DISTRIBUTION (25)

top holder share:

  • 5 %12 pts
  • 15 %9 pts
  • 30 %6 pts
  • 50 %3 pts
  • otherwise → 0 pts

top ten share:

  • 20 %13 pts
  • 40 %10 pts
  • 60 %6 pts
  • 80 %3 pts
  • otherwise → 0 pts

ACTIVITY (20)

indexed transactions (lifetime):

  • 100,000 txs12 pts
  • 10,000 txs9 pts
  • 1,000 txs6 pts
  • 100 txs3 pts
  • 1 txs1 pts
  • otherwise → 0 pts

indexed token transfers (lifetime):

  • 10,000 transfers8 pts
  • 1,000 transfers6 pts
  • 100 transfers4 pts
  • 10 transfers2 pts
  • 1 transfers1 pts
  • otherwise → 0 pts

CONTRACT (15)

ERC-20 confirmed → 5 pts · no EIP-1967 proxy → 4 pts · verified source → 6 pts (excluded when the indexer is down)

FRESHNESS (10)

reads ≤ 5 blocks behind → 6 pts · ≤ 504 pts · else 1 pt

indexer ≤ 1,000 blocks behind → 4 pts · ≤ 10,0002 pts

SAND SCORE describes observable on-chain conditions. It is not a prediction, recommendation, or guarantee. See METHOD for a worked example.

SECTION 08

SOURCES

  • RPC — Robinhood Chain JSON-RPC (eth_getBalance, eth_getCode, eth_getBlockByNumber, eth_getTransactionByHash, eth_getTransactionReceipt, eth_getStorageAt, eth_getTransactionCount, eth_chainId, eth_blockNumber)
  • CONTRACT — eth_call answers from the contract itself
  • POOL — pair/pool state read at the pinned block
  • INDEXER — Blockscout API v2: tokens (+ market figures), token counters, holders, addresses, address counters, ERC-20 balances, transactions (decoded), transaction logs (decoded), verified smart-contract source/ABI, network stats; always labelled, always with a retrieval time
  • CALCULATED — derived values; the formula is printed in RAW

Hover any badge for the exact origin. Open RAW on any readout to see every read in order.

SECTION 09

LIMITATIONS

  • JSON-RPC cannot enumerate holders or list transactions by address; those screens depend on the indexer.
  • The public node is not an archive node: reads are pinned to the current head, not to arbitrary old blocks.
  • Only registered factories are consulted; a token traded elsewhere shows NO POOL, not a guessed price.
  • Interface detection is evidence-based: ERC-721/1155 are YES only through ERC165; selector scans alone produce UNKNOWN.
  • Holder concentration counts pools, lockers and bridges as holders because the chain does not say which is which.
  • Volume, market history and off-chain facts are never printed.

SECTION 10

RPC

CHANNEL 4663 · NATIVE ETH · PUBLIC RPC https://rpc.mainnet.chain.robinhood.com · EXPLORER https://robinhoodchain.blockscout.com

The server tries RH_RPC_URL, then ALCHEMY_ROBINHOOD_RPC_URL, then the public RPC, failing over on transport faults only. Every response verifies eth_chainId first; a mismatch suspends readouts and prints CHANNEL MISMATCH. Private endpoint keys never reach the browser: the page talks to same-origin routes and a read-only relay.