How it works
Every choice in here either makes your position safer or your fees bigger. Here is which is which.
Shares are denominated in liquidity, not value
Shares are minted and burned strictly in proportion to Uniswap liquidity, the quantity the pool calls L:
This is the quiet win in the whole design. L is decimals-agnostic, cannot be moved by sending tokens to the contract, and does not change when the price changes, so joining and leaving are immune to price manipulation. That is the usual way vaults holding volatile pairs get attacked, and here the attack simply has nothing to grab.
The 1e6 scale applies to the first deposit and nothing else, and that detail protects you. The conventional defence is an always-on offset, which in an auto-compounding vault quietly becomes a dilution vector: compounding adds liquidity without minting shares, so the ratio it depends on drifts until the offset starts over-issuing shares to new depositors at the expense of everyone already in. Every conversion after the first is exactly proportional here, so nobody can be diluted by someone else's deposit.
Compounding is permissionless
Anyone may call compound(). There is no key, no allowlist and no special access, and whoever calls it pays the gas. It also runs inside every deposit, before that deposit is priced.
The ordering there is worth a moment. Harvesting first raises what a share is worth, so an arriving depositor pays the higher price and the fees stay with the holders who were there while they accrued. Doing it after the mint would hand a slice of your earnings to someone who turned up a second ago.
Fees below a materiality threshold, 0.5% of the position by default, are left in the pool rather than banked, because collecting them would cost more gas than they are worth. Nothing is lost by waiting. They keep earning where they sit, and burning the last share pulls out the entire position including every uncollected fee.
The keeper holds no privilege
A maintenance caller runs on a schedule and triggers compounding between deposits. In most protocols a "keeper" is a governor wearing a hat. This one is genuinely just a convenience, and here is exactly how little it can do.
- It can do nothing a stranger could not do with their own gas, because the functions it calls are permissionless.
- It cannot move anyone's funds, cannot pause anything, and cannot change any parameter.
- Its key funds gas and nothing else. There is no key here that a user needs to trust.
- If it stopped running tomorrow, vaults would still compound on every deposit, and anyone could trigger a harvest directly.
It also simulates the call before sending it, and skips when the simulation says there is nothing to bank. That keeps a materiality threshold from being paid for in wasted gas on every tick, and it means the decision logic is the contract's own rather than a second copy of the rule that could drift from it.
Price safety, split by job
A two-token position has to price one side to report a single-asset value, and that is the only price-dependent surface in the vault. Splitting it by job gets you the best of both: reads that always answer, and writes that refuse a manipulated price.
A pool whose oracle carries fewer than 60 observations cannot be wrapped at all, so every vault that exists has an oracle deep enough to defend it.
Full range versus a band
Full range is the default, and the measurements are the reason. A narrow band sounds like the sophisticated choice, so it is worth knowing what it actually earned here.
Only 5% of pools never left a ±10% band. So rather than offer a setting that would quietly halve your fee income, the band ships only alongside permissionless re-centring that follows the price. If you want a band, you get the machinery that makes it work.
What re-centring costs, and what bounds it
Every re-centre burns the position, swaps toward the new balance and re-mints. That realises divergence loss and pays the pool's own fee on the swapped portion, roughly 0.5% of the rebalanced value on a 1% tier. A real cost for a real benefit, and reported on chain every single time rather than absorbed quietly.
Re-centring is permissionless too, and four gates make sure it only happens when it genuinely helps you:
- The average price must be outside the band, plus a buffer. Spot alone is not enough, or a single wick would authorise a re-centre.
- An hour must have passed since the last one. This is what bounds griefing: without a floor on the interval, anyone willing to push the price back and forth could drain the vault through swap fees without ever holding a share.
- Spot must sit near the average, since the swap and the mint both execute at spot.
- A floor on the value that survives. A re-centre that would give up more than the caller authorised reverts instead of completing, and both sides are priced at the same moment so the comparison sees execution cost rather than the price move.
