USDC yield from real Uniswap v4 trading activity.
Two distinct streams, kept separate on purpose:
- Market yield — variable, uncapped. Each hooked swap routes 80% of its fee into
poolManager.donate(). Per donation event, v4 credits each position L_i / Σ L_k, where the sum is over every position on this exact PoolId (currency pair + fee + tickSpacing + hooks) whose tick range covers the active tick at the donation block. Liquidity is sampled per-event, not averaged; “liquidity-time” is the count of donations a position is in-range for. Late LPs do not retroactively dilute past donations, but they do dilute every future one in proportion to their L. Vault liquidity is presently dominant in this range — a market state, not a protocol invariant. - Incentive yield — capped, scheduled, conditional. A 180-day early-depositor program funded from treasury inflows. Today the epoch pool reads live below; caps and windows are on-chain.
Pair: WETH / USDC.
Vault yield vs passive v3 LP baseline
The only chart that answers “does the hook actually beat v3?”. Methodology is committed up front; numbers fill in with on-chain history. We render the comparison even on days the baseline wins.
convertToAssets(10^shareDec) / 10^assetDec − 1. Share price advances at flush blocks; this is realized only, excluding latent v4 fee growth.Methodology — exactly how each number is computed
- Vault realized yield =
vault.convertToAssets(10^shareDec) / 10^assetDec − 1whereshareDec=assetDec + _decimalsOffset()(currently — for shares, 6 for assets). First deposit mints at parity by ERC-4626 convention, so this ratio − 1 is the cumulative realized return. Excludes uncollected v4 fees by design — see SPEC §2.2. - v3 baseline = passive full-range LP yield on Uniswap v3 WETH/USDC 0.05% (Arbitrum) over the same time window. Computed from
feeGrowthGlobal0X128 / feeGrowthGlobal1X128deltas, divided byliquidityat sample time, marked to USDC at spot. This is conservative: tighter v3 ranges earn more, but they also have non-zero re-balance cost we’re not modeling. - Window — rolling 7 days, refreshed hourly. Below the threshold we show neither vault APR nor baseline APR; both numbers would be statistical noise.
- Honesty contract — when the v3 baseline beats the vault on a given window, we render the window. If we hid losing windows the chart would be marketing, not signal.
What happens when you deposit USDC.
- 01
You deposit USDC into this vault.
- 02
The vault can deploy it as a single-sided concentrated-liquidity position on Uniswap v4 on the WETH / USDC pool. While the live price sits above that range, the position is parked in USDC and not active swap depth yet.
- 03
Swaps routed through the hook attempt to apply a 25 bps fee (1.5× in volatile blocks, hard-capped at 50 bps).
- 04
By default 80% of that fee is sent into
poolManager.donate(). The atomic unit is the donation event (one per distribute call). Per event, v4 credits each position L_i / L(t_d), where L(t_d) is the pool’s active liquidity scalar on this exact PoolId. Yield is time-integrated exposure to those events, not a count of them: one large fee at a moment of small L can outweigh many small ones at high L. Late LPs cannot retroactively dilute past donations; they do dilute future ones in proportion to their L. (The other 20% funds the treasury. Treasury share is owner-adjustable, hard-capped at 50%.) - 05
Your share price is the single accounting anchor:
totalAssets() / totalSupply(). There is no per-user reward tracking — all attribution is share-based. ERC-4626 leavestotalAssets()implementation-defined; this vault uses a discrete-harvest model: uncollected v4 fee growth is excluded fromtotalAssets()and imported step-wise whencollectYield()(permissionless) or anydeposit/withdrawflushes — a choice that keeps the realized side tamper-evident, not a v4-level invariant. As a consequence, share price is a step function: continuous in spot between flushes, with upward jumps at each flush. Between flushes, the displayed price is a lower bound on lifetime entitlement; anyone can callcollectYield()first to trade against the post-flush price.
collectYield() to harvest accrued fees into share price — that part is permissionless. Moving the range itself (rebalance()) is owner-only, so if the market price drifts outside the configured ticks the position can sit idle until the owner repositions it.Vault overview
Live on-chain state. Deposit to start earning fee yield.
Real USDC sitting in epoch 0
Verify these numbers yourself. Every value below is read live from BootstrapRewards and — on Arbitrum One.
Click Read Contract on Arbiscan and call epochs(0). The first return value is bonusPool in USDC units (×106). It will match the value above. Anyone can also call payoutAsset.balanceOf(bootstrap) and confirm the USDC actually sits in the contract — not in a treasury wallet.
Untracked balance. If contract balance > bonus pool, anyone may call pullInflow() on BootstrapRewards to commit the residual into the active epoch's bonus pool. Permissionless, idempotent.
Connect a wallet to preview your bonus eligibility.
See exactly what a deposit earns on live pool data.
Project your share of hook fees and the early-depositor bonus using live pool numbers — TVL, share price, fee distribution split, bonus pool. Every input is on-chain and editable.
Reserve desk
Live, public state of the vault's single-sided reserve sale on the hook. Anyone can verify the offer, the price, and every fill — no indexer, straight from chain.
Quote source & gate. Vault price is posted by an allowlisted keeper (Safe-managed). Each fill is gated on-chain against live spot, directionally: fill ⇔ P_spot ≤ P_vault when the vault sells token1, and fill ⇔ P_spot ≥ P_vault when it sells token0 (PRICE_IMPROVEMENT mode; VAULT_SPREAD flips the inequality). A stale or mispriced quote cannot execute against the pool. Spec §3.4 ↗
The vault has no active reserve offer. New offers appear here the instant the operator posts one on-chain.
Swap directly through the hook
Routes through The-Pool's own Uniswap v4 PoolKey. 80% of every hook fee flows back to in-range LPs (including you, if you've deposited).
Swaps are trades. They do not mint vault shares; you receive the output token directly.
NoLiquidityToReceiveFees can revert.How it works
Four contracts, one transaction per swap. No off-chain keepers, no token.
You deposit USDC. The vault works best when WETH / USDC trades inside its selected range. If price is outside that range, some funds may wait in USDC instead of being forced into a bad trade.
A reserve keeper can help reduce idle time by offering unused reserves to swaps. Reserve quotes are posted by an allowlisted keeper (Safe-managed) and gated on-chain by an AMM-spot price-improvement check before any fill — discretionary input, deterministic gate.
Security — anti-sandwich reference-price gating, two-step ownership handoff, ERC-4626 virtual-shares inflation mitigation, SafeERC20 on every transfer.
- Impermanent loss. Concentrated-LP exposure is not USDC-flat: when WETH price moves inside the range, the position rebalances against you relative to a USDC-only basis.
- Range-shift risk.
rebalance()is owner-only via the Safe. Frequency and tick choice can change fee capture timing; depositor accounting is unaffected. - Pro-rata dilution. The 80% donation is shared across every in-range LP. If third-party LPs join the same range, the vault's share of each donation falls accordingly.
- Bonus is conditional. Epoch pool is funded only when treasury inflows arrive and
pullInflow()is called. Caps and windows are on-chain; funded balance is shown live below. - Reserve quote is discretionary. Posted by an allowlisted keeper. Fills are still gated by an on-chain AMM-spot price-improvement check.
- Custody & admin. Vault is
Pausableand owned byVaultOwnerController, which is owned by a Safe multisig. Hot keeper can only call typed reserve operations — no withdraw, no rebalance. Hook, vault, and distributor contracts are non-upgradeable; migration would require redeployment.