Built on Robinhood Chain · #58,078,963

Weir

A vault tells you what your shares are worth. That is not the same as what the vault will let you take, and the standard says the second number is a promise. On this chain, 14 of 43 live vaults will not keep it.

ERC-4626 vault 26 properties run on chain the crest is shared pro rata

What the standard actually says

A quote is not advice.
It is a claim about the next transaction.

EIP-4626 is unusually blunt about one function:

maxWithdraw — “MUST return the maximum amount of assets that could be transferred from owner through withdraw and not cause a revert.”

So it is falsifiable. Ask a vault what you can take, then ask it to give you exactly that, and see which answer it stands behind. No fork, no testnet, no key: eth_call runs the vault's own bytecode against its own storage at head, and costs nothing.

overstated the vault quoted a number and reverted on it4
quoted nothing maxWithdraw returned zero — nothing may leave10
honest paid the quote in full, and refused one unit more27
understated paid it, and would have paid more — safe, but not “the maximum”2

49 vaults in the census; 43 could be measured at head. 4 have no shares outstanding and 2 had no holder inside the scanned window — both are excluded and counted rather than folded in. Every row is published.

The number a holder feels

The quote is the last thing you check, and the first thing that fails.

14 of 43live vaults that will not honour the exit they quote
100.0%of a holder’s stated worth that can actually leave, at the median
100.0%of a vault’s own stated assets that it is actually holding, at the median

The largest position quoted nothing

In STATE, the largest holder this sweep reached owns shares the vault itself values at 71,348,022 DEEP. maxWithdraw for that address returns zero. The vault is holding 0.0% of what it says it is worth.

0xbfb7b3ff3d498a559b946b836d26f0e168f273d5

Why it is called a weir

Measured where the water leaves.

A weir is a low wall across a channel with a notch of known shape. Engineers build them because the height of water over the crest gives you the discharge — the flow is not estimated from the size of the reservoir behind it. It is measured at the point where the water actually goes over.

Which is the whole disagreement. A vault's balance sheet is the reservoir. What a holder needs is the discharge, and those two numbers stop agreeing the moment a vault deploys anything.

A weir on the Heubach at Dülmen: a timber sill across the channel with water running under the walkway
A weir on the Heubach, Dülmen. Photograph by Dietmar Rabich, CC BY-SA 4.0.

How Weir answers it

Two bounds, and the exit path reads the same function that published them.

The inversion

maxWithdraw is not convertToAssets(balanceOf(o)). It is the largest a for which previewWithdraw(a) still fits in your balance — solved exactly, through the same roundings withdraw will perform.

With an exit fee there are two nested ceilings between assets and shares. Converting straight through them lands one unit high, and one unit high is a revert.

The derivation →

The crest

A vault that has deployed its assets is worth more than it can pay. crest() is what can be paid this block, and a holder's claim on it is pro rata — not first come.

So a shortfall is shared in proportion. Whoever arrives first cannot take the crest down to nothing and leave everybody behind them holding a quote the vault can no longer honour.

How the split works →

Executed, not asserted

26 properties and 20 sabotages, run on this chain's own EVM.

The properties run for real

All 26 run through eth_call with no to — real creation code on the real evaluator, against real chain state. 26 of 26 hold.

And each guard is broken on purpose

The contract is compiled again 20 times, each with one defect, and every defect must be caught by a specific property. 20 of 20 behave as declared.

Including the ones that survive

1 sabotage survives and is declared, with the reason. Publishing only the caught ones hides where the floor is.

Every property and every sabotage, with its result →

Ask it what you can take.

The app reads maxWithdraw and crestFor straight from the contract, and builds the exact calldata it would send. No backend, no API key, no private key.

Open the app