Fees and payouts
Fees
Every trade pays a 1% to 15% tax, chosen by the creator, in stock. After graduation a 0.20% pool fee is charged on top. A launch costs 0.0005 ETH. There is no sell spike and no sweep tip.
The tax
| trade | taxed on | where it is taken | what happens to it |
|---|---|---|---|
| curve buy | the stock paid | in the curve | protocol 30% / creator ≤50% / treasury the rest; claims inside the curve |
| curve buy in the opening window | the token output | in the curve | the premium over the tax is burned |
| curve sell | the gross stock output | in the curve | the same split |
| pool buy, exact input | the stock paid | the hook's beforeSwap | a stock claim of the hook, paid out by sweep |
| pool buy, exact output | the stock paid, grossed up r / (1 − r) | the hook's afterSwap | the same |
| pool sell, exact input | the gross stock output | the hook's afterSwap | the same |
| exact-output sell | refused (ExactOutputRefused) |
- The tax is
floor(paid × taxBps / 10000). A payment under10000 / taxBpsraw stock units pays none; this matters only for a stock with very few decimals. - On an exact-input pool buy the hook takes the tax before the pool moves. Only
1 − rateof the payment meets the pool, and the pool fee is charged on that net amount. A buy that then stops at its price limit revertsPartialFillRefused, wrapped by v4; decoding it. - A sell is taxed after the swap on what it actually received and may fill short.
- The treasury's own swaps are untaxed.
Taxed(id, selling, inToken, moved, tax, rateBps):movedis the stock the swap moved; on a buy the trader paidmoved + tax.
The pool fee
The v4 pool charges 0.20% (lpFee 2000) in the input currency of each swap. The factory accepts 1 to 3000
(0.30%) for future launches; the fee is frozen per pool.
| side | charged in | goes to |
|---|---|---|
| buy | stock | the vault's positions, then the treasury's buybackStock when anyone calls V2LiquidityVault.collectFees() |
| sell | the token | burned on the same call |
FeesCollected(stockToTreasury, tokenBurned) reports both. Neither amount is booked as strategy cost basis.
The pool fee feeds the buy-back budget, never the strategy's capital.
What a buyer sees
On a graduated pool a buyer pays the tax plus 0.20% on the net amount, both in stock: about 1.2% at the minimum tax. On the curve a buyer pays the tax and, in the opening window, the premium in tokens. The quote page says how to show both.
The launch fee
launchFeeCurrency is Native and launchFeeAmount is 0.0005 ETH, sent straight to protocol at launch
with no swap and no price lookup. The request's maxFee is the most the launcher agrees to pay; a fee over it
reverts.
Payouts
Three parties share every tax: the protocol (30%), the creator (up to half) and the treasury (the rest). A fourth, the keeper, is paid per strategy action. Nothing is paid automatically: each payout is a permissionless call.
On the curve
Fees accrue inside the curve as claims. claimFees(recipient) pays that recipient's claim to that recipient and
nobody else; anyone may call it, and it keeps working after graduation. A blocked recipient cannot stop the other
two claims or curve trades. claimable(recipient) and totalFees() read the state; FeesClaimed reports a
payout.
In the pool
Fees sit in the hook as ERC-6909 stock claims per pool. sweep(poolId) pays buy-side and sell-side fees to the
three recipients in one call, each currency on its own leg so that one that cannot settle never strands the
other. sweepTipBps is 0: the caller is paid nothing. owedProtocol, owedCreator, owedTreasury and
accrued(poolId) read what is waiting; Swept reports a payout. There is no token-denominated fee inventory and
no owner conversion step.
The protocol's share
The protocol's 30% of every tax arrives in stock at protocol, the Safe. 30% of that income buys $HEDGE back,
which is 9% of every collected tax. The Safe makes these purchases periodically, by hand; no contract does it, so it
is a commitment of the Safe and not a payout anyone can call. The launch fee is not part of it. See
how $HEDGE works.
The treasury's share
The treasury's share of the tax is income. On arrival it is unbookedStock(); book(), or the next execute(),
books it at the live price. Lots-family and engine strategies book it as inventory; the Buy-back strategy sends
all income to buybackStock. The pool fee's stock side goes to buybackStock for every kind.
The keeper's reward
bountyBps (0.1%) of what the action produced, paid in the asset it produced, to the caller of execute() or
buyback():
| action | basis | paid in |
|---|---|---|
| take-profit (Lots family) | the profit | stock |
| stop (Lots family) | the proceeds | USDG |
| dip buy, recovery buy (Lots family) | the spend | USDG |
| engine sale (Spot, Rebalance) | gross USDG output | USDG |
| engine buy (Spot, Rebalance) | gross stock output | stock |
| buy-back (every kind) | the tokens bought | the token |
book(), sweep, collectFees, claimFees | nothing |
A 2,000 USDG sale at a 3% gain pays about 0.06 USDG. The release note states that the reward is too small to pay an outside keeper and that the protocol runs one; the calls remain open to anyone.
Changing a payout address
| address | who changes it | how |
|---|---|---|
| the protocol's, per pool | the owner | setProtocol(poolId, to), no delay |
| the creator's, per pool | the owner proposes, the creator decides | proposeCreator(poolId, to); after TAKEOVER_DELAY (14 days) anyone may acceptCreator within ACCEPT_WINDOW (14 days); one vetoCreator call from the creator ends it and bars a new proposal for VETO_QUIET (180 days) |
| the curve's recipients | nobody | immutable |
The creator address must be able to call vetoCreator: an EOA or a Safe, not a splitter.
Treasury and buy-back
Every launch has a treasury. It receives 30% of the raise at graduation, runs one strategy chosen by the creator before launch, and can only ever trade its stock against USDG on the listing's pool, inside the health gate. What it earns buys the token back in the token's own pool and burns it. Holders have no claim on the treasury itself (none today; one may be added later).
The seven strategies, with their parameters, floors and defaults, are on Concepts.
The health gate
health() is true when all of the following hold:
| condition | source |
|---|---|
the stock's Chainlink feed is fresh and oraclePaused() is false | PriceOracle |
| the market is open, or the launch's staleness band allows a bounded closure-time price | TradingCalendar, bandBpsPerHour |
the stock pool's spot is within maxDeviationBps (0.5%) of the oracle and of the pool's 600 s mean | the listing's V3 pool |
| the pool's observation ring serves the window | the V3 pool |
A passing trade executes on the V3 pool with a price limit maxSlippageBps (1%) off the oracle and fills only
what fits inside it. During a scheduled closure the stock/USDG TWAP is guarded and a stop never fires on a
pool-only price. The staleness band is bandBpsPerHour, 0 to bandCeiling(stock), total cap 3000; 0 means
Chainlink only and market hours only. Before graduation health() returns (false, 0).
Booking and the execute order
Stock that arrives, the graduation capital, the tax share, a donation, is unbookedStock() until book() books
it at the live price. execute() books pending stock first, then processes a due stop, then a due take-profit,
and buys a dip only when neither sale is due; an execute() that ends in NotDue rolls back its tentative
booking, so call book() on its own when stock is waiting and no action is due. The inherited takeProfit(id),
stopLoss(id) and buyDip() selectors revert on v2.
The buy-back
Stock set aside for the burn sits in buybackStock. buyback() spends it on the token in the token's own v4
pool and burns what it bought. It ignores the calendar, because the token pool never closes, and prices itself
off the pool's 600-second TWAP (the terminal price serves as the first anchor), bounded by maxBuybackImpactBps
(3%) and paced by buybackCooldown (10 s). The Lots and engine kinds offer buybackChunkUsdg (500 USDG) per
call; Percentage buy-back and Cycle offer a tenth of the budget. The treasury's own swaps are untaxed.
buybackStock is fed by realised profit (Lots family), the payout share of a gain (Spot, Rebalance), all income
(Buy-back), and the stock side of the pool fee (every kind, through collectFees()).
What burns
| burn | source | event |
|---|---|---|
| opening premium | curve buys inside the window | Bought.burned |
| buy-back | buyback() | Buyback.tokenBurned |
| pool fee, sell side | collectFees() | FeesCollected.tokenBurned |
Graduation burns nothing, and locked liquidity is not a supply reduction.
The strategy registry
The kind is chosen before predict with V2TreasuryDeployer.setStrategyKind(symbol, nonce, kind); kind 0 needs
no call. It is part of the treasury's CREATE2 address and so of terms. The registry is append-only. The ids are
those the release scripts produce, in order:
| kind | name | contract | proxy logic |
|---|---|---|---|
| 0 | Lots | HedgeFunV2UpgradeableTreasury | HedgeFunV2UpgradeableTreasuryLogic |
| 1 | Buy-back | HedgeFunV2UpgradeableBuybackTreasury | HedgeFunV2UpgradeableBuybackTreasuryLogic |
| 2 | Spot | HedgeFunV2UpgradeableEngineTreasury | HedgeFunV2UpgradeableEngineTreasuryLogic, schema 1, policy V2RebalancePolicy |
| 3 | Rebalance | HedgeFunV2TradablePercentEngineTreasury | HedgeFunV2TradablePercentEngineTreasuryLogic, schema 3, policy V2TradablePercentRebalancePolicy |
| 4 | Percentage buy-back | HedgeFunV2PercentBuybackTreasury | HedgeFunV2PercentBuybackTreasuryLogic |
| 5 | Cycle | HedgeFunV2UpgradeableCycleTreasury | HedgeFunV2UpgradeableCycleTreasuryLogic |
Kinds 2 and 3 consult a stateless policy with STATICCALL. The policy proposes one intent, hold, buy or sell;
the treasury checks the policy's code hash, the nonce, the config hash, the live oracle, the cooldown, the
direction, the per-action size and the daily turnover before it swaps.
Behaviour by market
| market | Lots, Percentage buy-back, Cycle | Buy-back | Spot, Rebalance |
|---|---|---|---|
| rising | sells at each target; buys again on a dip under the last sale, or once on a further rise (Cycle) | buys and burns from fees | sells slices as the stock share passes the band; gains fund the burn |
| ranging | sells high, buys the dip | the same | trades each swing outside the band |
| falling | buys each dip step; sells nothing without a stop | the same | buys toward target; no gain, nothing to the burn |
| flat | nothing triggers | the same | nothing triggers |
| market closed | the stock leg waits; buy-backs continue off the token pool | the same | the stock leg waits; buy-backs continue |
Shared by every kind
- Stock or USDG sent to a treasury is a donation that joins the next observation. No withdrawal, no redemption.
- At most 128 distinct-cost lots; at the limit, booking and dip buys wait for a sale.
health(),unbookedStock(),buybackStock(),params(),totalBurned()andtotalStockSpentOnBuybacks()are the views every kind serves; reading state lists the rest.