Correctness

Your historical P&L is wrong. Here’s the query that proves it.

Robinhood’s stock tokens keep raw ERC-20 balances static and express corporate actions through a multiplier. Any historical valuation that skips that term is arithmetically incorrect the moment an instrument splits or pays a dividend — and every provider we surveyed skips it.

NVDA · uiMultiplier by blockpiecewise constant
0.02.34.63.80M3.96M4.31M4.52M
  • 3,960,000CASH_DIVIDEND $0.04/sh→ ×1.0042
  • 4,310,000FORWARD_SPLIT 4:1→ ×4.0168
The arithmetic

One term, skipped by everyone

This is not a matter of interpretation. It is a multiplication with three terms, and the middle one is time-dependent.

value_at(N) = balanceOf(addr, N) × uiMultiplier_at(N) × price_at(N)
                                 ^^^^^^^^^^^^^^^^^^
                                 everyone skips this
The same question, two answersNVDA · block 4,200,000

What was this position worth at block 4,200,000? The balance never moved — Robinhood’s stock tokens keep raw ERC-20 amounts static and express corporate actions through uiMultiplier(). Apply today’s multiplier to a past balance and the answer is wrong by construction.

Every provider we surveyed
balanceOf(NVDA, 4,200,000) × uiMultiplier() ← today's, not the block's × price_at(block)

$9,210.00

Uses the current multiplier of 4.000000. The balance is right; the scaling factor is from the wrong point in time.

RobinhoodRPC
balanceOf(NVDA, 4,200,000) × uiMultiplier_at(4,200,000) × price_at(block)

$2,302.50

Uses the multiplier that was actually in force at that block: 1.000000.

Error +300.0%Cause FORWARD_SPLIT 4:1 on 2026-08-11
Why it happens

The balance is supposed to stay still

This is not a bug in Robinhood's design. It is a deliberate choice that generic EVM tooling was never built to handle.

Stock tokens are ERC-20 with 18 decimals, extended by ERC-8056, the Scaled UI Amount Extension. A dividend or split adjusts the shares-per-token ratio while leaving raw balances untouched until redemption.

That means a holder’s balanceOf() is unchanged across a 4-for-1 split. Nothing looks wrong. The scaling lives entirely in uiMultiplier(), and it is time-dependent.

Because dividends are reinvested through the multiplier rather than paid out, a stock token tracks the total return of its underlying — price change plus reinvested dividends. A provider reporting price return alone is misreporting performance even when their balance is right.

Stock token interface (ERC-8056)solidity
// Raw balance — static across corporate actionsfunction balanceOf(address) returns (uint256); // The scaling factor, 18 decimals. 1e18 == 1.0function uiMultiplier() returns (uint256); // Underlying-share equivalent, for displayfunction balanceOfUI(address) returns (uint256); // Pending change, readable before it takes effectfunction newUIMultiplier() returns (uint256);function effectiveAt() returns (uint256); // Fires on dividend or split, carrying old, new, timestampevent UIMultiplierUpdated(    uint256 oldMultiplier,    uint256 newMultiplier,    uint256 effectiveAt);
Methodology

How we compute, and where we could be wrong

A correctness claim that hides its assumptions is a marketing claim. These are ours.

R1

Robinhood REST prices are raw underlying

Multiply by currentMultiplier before comparing to anything onchain. Stated in Robinhood's own docs, and the most likely source of silent error.

R2

Chainlink prices are already multiplier-adjusted

Never apply uiMultiplier() to a Chainlink price. Double-application is the mirror image of R1 and produces a number wrong by the square of the multiplier.

R3

Historical valuation uses the multiplier at that block

Never the current one. This is the bug in every incumbent's historical balance API.

R5

Stock tokens track total return, not price return

Dividends are reinvested through the multiplier. Reporting price return alone understates performance.

These are four of ten. The full set — including how we handle stale oracles, reorgs and session boundaries — is published at /docs/equities/correctness-rules, and is useful whether or not you buy from us. That is deliberate.

Verify it yourself

9 invariants, asserted against production

The suite is open source and runnable by anyone — against us, and against any competitor implementing the same endpoints. Results are published continuously.

npx @robinhoodrpc/invariants \  --endpoint https://api.robinhoodrpc.io/v1 \  --sample 500
  1. 01balance_ui == balance_raw × multiplier_at(block), for every sampled account and block
  2. 02Historical queries never apply the current multiplier when as_of is in the past
  3. 03Session boundaries match the published US equities calendar, including half-days
  4. 04A corporate action's details variant always matches its declared type
  5. 05Every SEQUENCED record reaches INCLUDED, DROPPED or REORGED — none dangle
  6. 06premium_bps recomputes exactly from the component fields in the same record
  7. 07tape_sequence is strictly monotonic with no gaps
  8. 08Candles flagged crosses_session_boundary genuinely span a boundary
  9. 09Reprocessing any range at a given code_version is byte-identical

Check our numbers before you trust them.

The invariant suite is public, the snapshots are signed, and every response carries the multiplier it applied. Start with a free key.