Built on Robinhood Chain

Arete

A high-water-mark fee is not a fee on your gains. It is a fee on the highest number the vault ever printed — and on how often it looked. Arete charges yours against your own entry price instead, and publishes the crest so you can check.

ERC-4626 vaultFee charged on your gainThe crest is a view function

DELL on Robinhood Chain, 260,145 blocks

Every price below is a Uniswap V3 swap that happened. 1,600 of them, decoded from the pool’s own sqrtPriceX96.

Where the position ended, against where it started−17.33 bps
The highest it got on the way+40.91 bps
A 20% high-water-mark fee, crystallising every block8.17 bps
The same fee, the same path, crystallising every 27.8 hours0.00 bps
Arete, charged against your own entry price0.00 bps

The problem

You are charged for a peak you never sold at

Write out what every performance fee in this category does at each crystallisation, and the sum telescopes. What comes out has no term for where the price ended.

A high-water mark

Charged on the crest

  • The bill is f × (highest price ever observed − the price you came in at). Exactly, on every path.
  • A vault that goes up and comes back has still charged you.
  • Looking more often finds a higher peak, so the fee is set by the vault’s cron.
  • The mark belongs to the vault. You inherit whatever the last holder’s luck left behind.

Arete

Charged on your gain

  • The bill is f × (your exit price − your entry price), floored at zero.
  • Two holders in and out at the same two prices pay the same fee, whatever the route.
  • There is no cadence in it. Nothing has to be crystallised at all.
  • Flat means nothing to pay, however far the vault travelled.

The identity

The fee is the crest, and nothing else

Let G be the share price with the fees taken so far added back, and M its running maximum over the moments the vault crystallised. Then the total given up per share is exactly

Φ  =  f × ( M − P0 )

Proved by induction on the record test, executed as property 11 on Robinhood Chain, and checked again on 3 real price paths where js/crest.js and the EVM must agree to the last unit — they do.

31/31properties executed on chain, not described
17deliberate defects, each confirmed caught or confirmed to survive for a stated reason
13.38bps: the median market’s peak above where it started
−0.90bps: where the median market actually ended

Measured, not argued

Same path, same fee rate, 2.67 bps or nothing

40 equity markets on Robinhood Chain, 45,536 real swaps. The only thing changing across these bars is how often the vault looks.

median fee (bps of stake) 2.67 0.1s 1,059.5 looks 2.67 1s 672.5 looks 2.11 10s 336 looks 1.40 2m 91 looks 1.06 17m 11 looks 0.47 2.8h 2 looks 0.00 27.8h 2 looks

Median across 40 markets of what a 20% high-water-mark fee charges, against the crystallisation interval. The median market moved −0.90 bps over its window; 19 of 40 were charged while their holder made nothing at all.

What the vault does

Three things nothing else in the category does

A fee on your own gain

Every holder carries a cost basis. At exit you are charged 20% of what you made, out of your own proceeds, and nobody else’s share moves.

  • Path-independent by construction, not by luck
  • Basis travels with the shares, so it cannot be shed by moving them
  • No crystallisation, so no cadence to argue about

The crest, as a view function

crest(), giveUp() and identityResidual() are ordinary reads. The vault publishes the quantity its fee is a function of, and the gap between the two.

  • Set both fee engines on one contract, so the comparison is like for like
  • The residual is minting rounding: worst observed 61 units in 1e+12
  • Crystallisation is permissionless and pays its caller nothing

Previews that know who is asking

ERC-4626’s previewRedeem(uint256) has no owner argument, so on a vault like this it can only return a bound. Ours returns the floor, and the owner-aware twin returns the answer.

  • previewRedeemFor and previewWithdrawFor are exact
  • withdraw is handed the owner, so it delivers what you asked for
  • What the design costs is published rather than hidden — see the FAQ

The tape

Every market, held and charged

The 40 busiest equity/USDG pools on Robinhood Chain over the scan window. “Held” is where the position ended against where it started. “Charged” is what a 20% high-water-mark fee would have taken.

RBLX1%
held+152.93 bps
charged45.90 bps
RBLX0.3%
held+125.24 bps
charged29.48 bps
GOOGL0.05%
held+26.88 bps
charged10.54 bps
DELL1%
held−17.33 bps
charged8.17 bps
GLD0.05%
held+33.20 bps
charged8.00 bps
TSLA0.05%
held−0.47 bps
charged7.00 bps
PLTR0.3%
held+26.39 bps
charged6.89 bps
MU0.3%
held+18.95 bps
charged6.77 bps
SPCX0.05%
held+18.02 bps
charged6.76 bps
HIMS0.3%
held+29.95 bps
charged6.25 bps
LULU0.3%
held+2.92 bps
charged5.63 bps
QQQ0.05%
held−8.15 bps
charged5.27 bps
NVDA0.025%
held−8.09 bps
charged4.29 bps
TTWO0.3%
held−5.15 bps
charged3.87 bps
LLY0.05%
held+3.26 bps
charged3.54 bps
SGOV0.015%
held+15.38 bps
charged3.24 bps
TSLA0.05%
held−17.38 bps
charged3.11 bps
MSFT0.3%
held+2.90 bps
charged2.99 bps
SLV0.05%
held−0.52 bps
charged2.94 bps
IBM0.3%
held−1.27 bps
charged2.70 bps
MSTR1%
held−144.87 bps
charged2.64 bps
AAPL0.05%
held−11.27 bps
charged2.25 bps
SGOV0.05%
held+9.01 bps
charged2.00 bps
GME1%
held+2.56 bps
charged1.84 bps
SPY0.005%
held−5.25 bps
charged1.70 bps
SPY0.01%
held−2.09 bps
charged1.50 bps
GLD0.3%
held+4.90 bps
charged1.11 bps
GME0.05%
held+2.85 bps
charged1.06 bps
COST0.3%
held+2.55 bps
charged1.06 bps
SPCX0.05%
held−3.81 bps
charged0.92 bps
SPY0.05%
held−2.99 bps
charged0.81 bps
NVDA0.011%
held−18.94 bps
charged0.73 bps
QQQ0.04%
held−8.70 bps
charged0.52 bps
TSLA0.3%
held−1.38 bps
charged0.49 bps
SGOV0.3%
held+2.18 bps
charged0.43 bps
GOOGL0.05%
held−18.01 bps
charged0.15 bps
NVDA0.05%
held−20.16 bps
charged0.01 bps
QQQ0.05%
held−4.71 bps
charged0.00 bps
BULL1%
held−478.05 bps
charged0.00 bps
MSFT0.05%
held−24.58 bps
charged0.00 bps

Several equities appear more than once: this chain has multiple pools per name, on more than one factory, and they are different markets with different prices.

Executed, not asserted

What the contract actually guarantees

Each of these is a numbered property run inside an eth_call against live chain state, and each has a deliberately broken build behind it that the suite has to notice.

Your fee is your gain

Two vaults, the same entry and exit price, wildly different routes: identical fee. A holder who is flat pays nothing.

Donations are all sweep can reach

sweep moves what was given to the vault and nothing that is owed. The state-changing surface is 10 functions and the build fails if an undeclared one appears. What the manager can still do is on the limitations page.

The fee is capped in code

30% maximum, immutable, checked in the constructor. There is no function that can raise it because there is no function that can set it.

Donations do nothing

Accounting is tracked, not read from balanceOf. Sending assets to the vault reprices no share, which is also the whole of the first-depositor defence.

FAQ

The short answers

What is wrong with a high-water mark?

Nothing, as an idea. The problem is what it charges. Take f of whatever the share price has made above the mark, then move the mark to the price that survives the fee, and the charges telescope: the total is exactly f × (highest price ever observed − the price you came in at). There is no term in that for where the price ended, so a vault that rises and comes straight back down has still charged you — on 19 of the 40 real markets measured here, the holder made nothing and was charged anyway.

Why does it matter how often the vault crystallises?

Because the maximum in that formula is a maximum over the moments the vault looked. Look more often and you find a higher peak. On the same 40 markets, a 20% fee crystallising every block charges a median of 2.67 bps and the same fee every 27.8 hours charges 0.00 bps. Nothing else about the vault changed.

Record statistics say how much: sampling a maximum at n points falls short of the continuous one by a universal constant over √n. The site checks that constant rather than quoting it.

How does Arete charge instead?

Every holder carries a weighted-average entry price. At exit you pay 20% of max(0, exit − entry) × your shares, out of your own proceeds. It is path-independent: two holders in and out at the same two prices pay the same fee whatever happened in between, and a holder who is flat pays nothing.

Then why does anybody use a high-water mark?

Because it needs one number for the whole vault and a per-holder fee needs a number per holder — and that has a real cost, which this site publishes rather than hides. Two accounts holding the same number of shares can redeem for different amounts, and previewRedeem(uint256) has nowhere to ask whose. It returns the worst case here, which the standard permits and which under-values a real holder. previewRedeemFor(owner, shares) is the answer, and withdraw uses it because the standard hands it the owner.

Everything else →