How harvesting works
The in-swap trigger, the minimums, the gas budget, and the manual full-gas path.
The pool's LP program accrues swap fees on both sides. A harvest — automatic inside swaps once fees pass your minimums, or manual — splits each side from the gross, so the percentages mean exactly what they say.
The waterfall, per side
compound + buyback ≤ 100%, enforced at set-time
compound + burn ≤ 100% · burn must be 0 on a native main
Shares are WAD-scaled (1e18 = 100%). A side whose two shares sum below 100% must name a live recipient — below-100% means a remainder can exist, and value never goes nowhere. All of it is validated when the config is set, not discovered at harvest time. The exact formulas, the rounding direction and the conservation proof live in The split math; what happens when a recipient refuses its leg lives in Payouts & the owed ledger.
Auto vs manual
| path | trigger | who | gas |
|---|---|---|---|
| auto-harvest | a swap, once either side's pending fees reach its minMain / minSecondary | inherently public — any swap triggers it | hard budget; a heavy run reverts atomically (fees stay safe) and waits for the manual path |
| manual harvest(key) | a direct call, any time | owner-only, unless publicHarvest opens it to anyone | the caller's full gas — the natural path for heavy tokens |
type(uint256).max on a minimum disarms that side's auto-trigger. Both paths run the same split code — the rules apply identically whether the machine fired itself or someone called it.
Choosing the minimums
minMain / minSecondary are a pure economics dial: every auto-harvest costs the triggering swapper some gas overhead, so the minimums decide the trade-off between harvest freshness and per-swap cost. Set them so a typical harvest is comfortably worth more than the gas it rides on; on a quiet pool, higher minimums plus an occasional manual harvest(key) is the cheapest shape. Since both paths run identical code, no value is ever at stake in this choice — only timing.
The auto-harvest runs under a hard gas budget in its own frame: a run that would exceed it reverts atomically — fees stay pending, nothing is half-split — and the carrying swap completes untouched. A pool with pathological tokens simply gravitates to the manual path; it can never make trading worse.
Go deeper
The next two chapters take the split apart: The split math derives every leg, the rounding direction and the conservation identity; Payouts & the owed ledger follows the money out of the hook — including what happens when a recipient refuses it.
FAQ
What triggers an automatic harvest?+
A swap, once the position's pending fees reach your configured minMain/minSecondary. The harvest runs inside that swap under a strict gas budget.
Why did my swap not harvest?+
Either the minimums aren't reached, the minimums are disarmed (set to max), or the gas budget was exceeded and the harvest reverted atomically. Fees stay pending — nothing is lost.
Who can harvest manually?+
The program owner via harvest(key) with full gas — and once the owner is surrendered (0x0), the harvest becomes public and anyone can run it.
What are good minimums?+
High enough that the split beats the gas of running it, low enough to keep the pot fed. Testnets and high-traffic pools can go low; mainnet long-tail pools should set meaningful floors.
Does harvesting touch the pool price?+
No — a harvest collects the position's fees and routes them. It never swaps through the curve, so it cannot move the price or be sandwiched.