Varve Open the app
Built on Robinhood Chain #57,916,747

Varve

A share price is assets over supply. The supply is in the log forever; the assets are in a storage slot this chain forgets in 10.2 minutes. Exactly one half of your own return survives — so Varve writes the other half down while it is still true.

ERC-4626 vault One word commits to the whole history No archive node needed

What the chain can still tell you

49 live ERC-4626 vaults, 4.7 days of blocks

Vaults with no recoverable price at all20 of 49
Typical wait between two of them3.4 days
Same wait, for a Uniswap V3 pool0.71 s
State older than 10.2 mingone
ERC-4626 vault accounting Tradeable share token No lockup Every price move logged

The problem

One number is in the log. The other one isn’t

A share price is totalAssets / totalSupply. Every change in the supply emits a Transfer, so the denominator is reconstructible for ever from any node. The numerator moves when income arrives, when a loss is taken, when a fee is charged — and ERC-4626 defines no event for any of them.

Every other vault

A price you had to be watching

  • totalSupply: complete, from the Transfer log, at any past block.
  • totalAssets: a storage slot, and this chain keeps storage for 10.2 minutes.
  • Nothing fires when the vault earns. Nothing fires when it loses.
  • So the only prices in the record are the instants somebody happened to transact.

Varve

A record laid down as it happens

  • Every mutation writes a Layer carrying assets, supply and the kind of move.
  • Income and markdown are kinds of their own, so a reader can tell them apart.
  • chronology() is one word committing to the entire series, in order.
  • Replay the logs, recompute the word, compare. No archive node anywhere.

The measurement

Measured on Robinhood Chain, not argued

52 addresses emitted an ERC-4626 Deposit across 60 windows covering 2.07% of the chain. A topic match is a candidate, not an identity, so each was asked for the whole interface: 49 answered and are counted, 3 did not and are not. Every figure below is over one common 4.7-day window, the same one the control uses.

20 of 49vaults whose share price is recoverable at no block at all in the window
3.4 daystypical wait between two moments the price is knowable
0.359%and that is the best vault — steakUSDG, the busiest in the census
16,036deposits and withdrawals read, each pinning one price

The control

Does any vault log its own mark?

“No vault logs its price” would be a flattering thing to find and a wrong one if any of them does, so every distinct topic each vault emits was read and matched against a dictionary of real vault events. 10 of 49 emit something of their own, across 30 distinct topics — and exactly 1 of them emits one that carries the mark.

One vault out of 49

It is aRHUSDG, and the event is MetaMorpho’s UpdateLastTotalAssets(uint256) — which carries exactly the number ERC-4626 has no event for.

And it bought almost nothing

That event adds 1 block of coverage on top of the 72 the vault already had from ordinary traffic. It is simply a busy vault. Saying the event is what made it legible would be the flattering version.

The standard is still the hole

The finding is not that implementations are careless. It is that 48 of 49 add no such event, because nothing asks them to — and 20 of those pin no price at all in 4.7 days.

The other control

The same chain, done right

A Uniswap V3 pool’s price changes only when it trades, and every trade logs the price it left behind. 598,889 swaps over 150,000 blocks in 2,659 pools, inside the same window — so a pool’s price history is complete for ever and a vault’s is not, on the same node, in the same blocks. That is why this is a finding about a standard rather than about a chain.

0.71 smedian wait between two knowable prices, for a pool
3.4 daysthe same wait, for a vault
408,689×between them — and a lower bound, because 20 vaults never pin one and are censored at the window length

What Varve does

Three things, and one word that proves them

An ordinary ERC-4626 vault with no strategy, no upgrade path, no owner who can move the assets and no fee. What it adds is the record.

A layer per move

Deposit, withdraw, income and markdown each write one Layer carrying the vault’s assets and supply at that block. Those two numbers are the share price, exactly, with no division done by the writer.

  • Four kinds, so income is distinguishable from a deposit
  • A genesis layer, so the series has a start
  • A no-op writes nothing

A word for the whole series

chronology() is a running commitment to every layer in order. Replay the logs, recompute it, compare. A missing layer, a reordered one or an invented one all give a different word.

  • One storage slot audits an unbounded history
  • Readable now, about a past the chain has dropped
  • Executed as properties 3, 4 and 5

Nothing else to trust

Assets sit in the contract. Income arrives by transfer and anyone may book it. The one trusted entry point is disabled outright when the steward is the zero address, which is what the app deploys.

  • Tracked accounting, so a donation is not a price move
  • Reentrancy guard, tested with an attack that fires
  • Credits what arrived, not what was asked for

Why a varve

A record that cannot be written afterwards

A varve is the couplet of sediment a lake lays down in one year: pale silt in the meltwater season, dark organic mud under the ice. Count them and you have a calendar. The Lake Suigetsu core is read back more than 50,000 years and calibrates radiocarbon dating for everyone, and it works for exactly one reason — every layer was laid down at the time. Nothing reconstructs a missing year.

That is the whole design. A vault that did not write its price down while the price was true cannot produce it later, however much anybody wants it.

Pleistocene varved clay at Baumkirchen, Tyrol. Each couplet is one year, and none of them can be written afterwards.
Pleistocene varved clay, Baumkirchen. Each light-over-dark couplet is one year. Hermann Hammer (User:Haneburger), CC BY-SA 3.0.

The contract

Executed, not described

29 properties run on Robinhood Chain's own EVM through eth_call with no to — no testnet, no fork, no funded account, no key. Then the contract is recompiled with one deliberate defect at a time and each must be caught by a specific, related property.

29/29properties hold on the correct contract
21deliberate defects, each caught by a named property or declared a survivor
2expected to survive, each with a stated reason
57,971,442the block the suite last ran against
Read the Solidity

Questions

The obvious objections

Does a Deposit event not already tell you the price?

Yes, and that is the honest version of the finding. Deposit(sender, owner, assets, shares) pins the conversion rate at that instant, so a vault’s price is recoverable at the blocks where somebody entered or left. What it cannot tell you is the price at any other moment — and those are the moments you actually want, because they are the ones where you were holding and nobody transacted.

Measured: the median vault has a recoverable price on 0.0000% of the blocks in a common 4.7-day window.

Is this not just a pruned node? Run an archive one.

You can, and then the answer depends on who runs it. An event is part of the chain’s own record and every node that syncs carries it; a historical state read is a service somebody chooses to offer. The public endpoint for this chain does not offer it past about 10.2 minutes, which is what makes the difference visible rather than theoretical.

Why not just index the vault yourself?

Then the history exists as long as your indexer does, and a reader has to trust it. chronology() is the difference: one word, in the contract, that any reader can compare their reconstruction against. An indexer that dropped a layer is indistinguishable from an honest one until you have that word.

What is actually deployed?

Nothing, by this repository. /app deploys a vault from your wallet in one transaction; the site holds no key and there is no canonical instance. The state page says which part of this is which, one row at a time, rather than putting a blanket disclaimer at the bottom.