Skip to main content

Launch and curve

TL;DR
  • A launch sells a new token on a bonding curve priced in a listed tokenized stock; the sale share is fixed at 79.31% of a 1,000,000,000 supply, and every listing opens at a $2,140.38 FDV, so a full sale raises about $8,205 of stock.
  • The buy that crosses 79.31% graduates the launch in the same transaction: 70% of the raise is locked in a Uniswap v4 pool, 30% becomes the treasury's strategy capital, and the price carries over at about 23 times the open.
  • Every trade pays a 1% to 15% tax chosen by the creator, in stock, split protocol 30% / creator up to half / treasury the rest; after graduation a 0.20% pool fee on top goes to the treasury's buy-back budget. A launch costs 0.0005 ETH.
  • The creator chooses the tax, the opening window (0 to 180 s) and the strategy; everything is frozen at launch. Live on mainnet: deployed on 2026-10-06, and public launching is open.

Overview​

Hedgefun v2 is a launch protocol for strategy tokens. A creator deploys a token priced in a tokenized stock, the public buys it from a bonding curve, and once 79.31% of the supply is sold the launch graduates into a Uniswap v4 pool whose liquidity is locked permanently. 30% of the stock raised funds a treasury that trades that stock by a rule the creator chose, and what the treasury earns buys the token back and burns it.

Mainnet was deployed from these contracts on 2026-10-06, with the creator's ceiling raised to half, and public launching is open. The contracts page carries the address tables.

Key facts​

Quote assetthe listed stock, on the curve and in the pool; never USDG
Supply1,000,000,000 tokens, 18 decimals, minted once to the curve
Sale share79.31%, fixed in CurveDeployer; the creator chooses the opening window (0 to 180 s) and the tax (1% to 15%)
Opening FDV$2,140.38 per listing; a full sale raises about $8,205 of stock and graduates near a $50,000 FDV
Graduationinside the crossing buy; 70% of the raise to two locked v4 positions, 30% to the treasury
Feestax in stock on every curve and pool trade, split protocol 30% / creator up to half / treasury the rest; pool fee 0.20% to the buy-back budget; keeper reward 0.1%; launch fee 0.0005 ETH
StrategiesLots, Buy-back, Spot, Rebalance, Percentage buy-back, Cycle, Lots with reserve (kinds 0 to 6; kind 6 registered on 2026-10-06)
Upgradestreasury logic only, by the factory owner, through a controller with a fixed 2-day delay; the liquidity vault has no upgrade path

Changes from v1​

v1v2
Launchthe whole supply seeded as one-sided v4 liquiditya bonding curve, then graduation into v4
Capitalnone requiredbuyers fund the curve; 30% of the raise becomes treasury capital
Buy taxin the token, burnedin stock, split three ways
Sell spike after a buy-back90% decaying over 120 snone
Pool fee00.20%, to the buy-back budget
Strategyone rule, five numbersseven kinds, chosen per launch
Treasury logicimmutableupgradeable by the owner after a two-day notice
Keeper reward0.5%0.1%
Sweep tip0.5%0

v1 stays deployed and unchanged: Hedgefun Protocol v1.

Contracts​

Deployed once per chain​

contractrole
HedgeFunV2FactoryLists stocks (list, setListingGates), quotes a launch (predict) and performs it (launch, launchWithMetadata), records every launch in strategies(id) and curves(id), carries the Defaults every launch freezes. graduateCurve is called by the curve inside the crossing buy; graduate(id) is the public entry for a Ready curve.
CurveDeployerDeploys each launch's curve and liquidity vault. Constructed with one sale share, DEFAULT_SALE_BPS = 7931; setCurveConfig refuses any other. Holds the creator's opening window and up to 40 opening-premium exemptions. Executes the graduation in the factory's context.
TokenDeployerDeploys HedgeFunToken.
V2TreasuryDeployerRegistry of strategy kinds and policies; per-stock LP share (lpBps, default 7000, floor 1000); the creator's setStrategyKind and setEngineConfig. Deploys each treasury. Constructs the upgrade controller.
V2TreasuryUpgradeControllerschedule, cancel, execute for treasury logic upgrades; UPGRADE_DELAY = 2 days.
HedgeFunV2HookThe one Uniswap v4 hook every graduated pool runs on. version() = 3; address flags 0x28CC. Takes the tax in stock on both sides, keeps the per-pool ledger, pays it out on sweep.
HedgeFunV2TradeRouterbuy and sell with any ERC20 that reaches the stock through at most 3 canonical V3 hops; curve before graduation, v4 pool after.
HedgeFunV2NativeRouterETH in and out around the same route.
HedgeFunV2LaunchNativeRouterlaunchAndBuy: launch fee, launch and the creator's first curve buy in one ETH payment. Requires setLauncher(router, true).
TradingCalendarThe US equity calendar the health gate reads; the owner's halt.
PriceOracleOne per stock: Chainlink in USDG, with the calendar and staleness rules of the three prices.
V2RebalancePolicy, V2TradablePercentRebalancePolicyStateless policies for kinds 2 and 3. Called with STATICCALL; return one intent: hold, buy stock, sell stock.
kind code chunksTwo inert contracts per registered kind holding the treasury creation code.

Created per launch​

contractrole
HedgeFunTokenThe strategy token. A plain ERC20: no owner, no mint function, no pause, no transfer tax. Carries logo, description, socials.
HedgeFunBondingCurveThe sale: unsold tokens, the real stock reserve, the tax ledger, the hand-off to the factory.
the treasuryOne of the seven kinds. Receives 30% of the raise and every later tax share; trades the stock on the listing's stock/USDG Uniswap V3 pool.
V2LiquidityVaultOwns the pool's two positions. No function removes liquidity, makes an arbitrary call or upgrades. collectFees is permissionless.
the v4 pooltoken/stock, fee 0.20%, tick spacing 60, on the shared hook.

Release parameters​

The factory Defaults the release scripts construct the core with (V2MainnetDefaults.release()). Each launch freezes its copy at launch. The owner may change them for later launches.

parameterrelease valuemeaning
supply1,000,000,000 × 10¹⁸token supply
saleBps7931 (79.31%)share of supply sold on the curve; a constant of CurveDeployer
lpBps7000 (70%)share of the raise seeded into the locked pool; per stock in V2TreasuryDeployer, floor 1000
lpFee2000 (0.20%)pool fee, v4 units; the factory accepts 1 to 3000
tickSpacing60
minTaxBps, maxTaxBps100, 1500the creator's tax range
protocolBps3000 (30%)protocol share of the collected tax
maxCreatorBps5000 (50%)most a creator may take of the collected tax
spikeBps, spikeSeconds0, 0no sell spike
sweepTipBps0no sweep tip
snipeBps9900 (99%)buy rate at the launch second
snipeSeconds3default opening window; the creator may choose 0 to 180
bountyBps10 (0.1%)keeper reward on a strategy action, of what the action produced
maxSlippageBps100 (1%)a treasury trade's price limit off the oracle
maxDeviationBps50 (0.5%)most the stock pool may sit from the oracle for health() to be true; 125 on 1% pools
maxBuybackImpactBps300 (3%)a buy-back's price limit against the token pool's mean
buybackCooldown10 sleast time between two buy-backs
minLotUsdg5 USDGa treasury trade under this does not execute
buybackChunkUsdg500 USDGone Lots buy-back's offer
sellChunkUsdg2,000 USDGmost one strategy sale offers
launchFeeCurrency, launchFeeAmountNative, 0.0005 ETHpaid to protocol at launch

Contract constants: buy-back TWAP window 600 s; at most 128 distinct-cost lots per treasury; 40 opening-premium exemptions; 3 router hops.

Where the repository documents and the code differ

The release runbook in the contracts repository lists the protocol share as 20%. The deployment code sets protocolBps to 3000, and the fee document dates the move to 30% to 2026-10-05. The values here are the code's.

Not in this release​

itemstatus
dividend and income kindsin source; not registered on any release registry. Proxy kinds can receive a compatible dividend implementation later through the controller
ETH-paired launchesv2.1

Launch lifecycle​

A launch goes through three states, all held by the curve: Active (0), Ready (1) and Graduated (2). Ready exists only inside the crossing buy's transaction.

At launch​

factory.launch(request, terms) or launchWithMetadata(request, terms, metadata), paid with the 0.0005 ETH launch fee, does four things in one transaction:

  1. Deploys HedgeFunToken and mints the entire supply, 1,000,000,000 tokens, to the curve.
  2. Deploys HedgeFunBondingCurve with a stock reserve of zero and the creator's frozen terms.
  3. Deploys the treasury of the chosen strategy kind, inactive: health() returns (false, 0) until graduation.
  4. Records the launch in strategies(id) and curves(id) and emits Launched and CurveLaunched.

You must quote first: predict(request) returns the token and treasury addresses and terms, a hash of every input the launch is built with. If any default, listing, gate or registered choice moves between the quote and the launch, launch reverts Restated. The creator's own first buy may sit in the same transaction through HedgeFunV2LaunchNativeRouter.launchAndBuy.

While the curve is active​

Buyers pay the stock into the curve, less the tax, and the price rises with each buy. Sellers get stock back, less the tax, and the price falls. The tax accrues inside the curve as claims for the protocol, the creator and the treasury; anyone may push a recipient's claim out with claimFees(recipient). For the first 0 to 180 seconds the buy rate carries the opening window premium.

The curve has no deadline. A curve that never reaches its target stays Active, and holders can sell back to it for as long as the stock itself transfers.

The crossing buy​

The buy that lifts the real reserve to the target performs the graduation itself. The curve goes Ready, releases its trade lock, and calls factory.graduateCurve(). The factory releases that curve's recorded reserve, initialises the v4 pool at the curve's last price, has the vault seed two locked positions, sends 30% of the raise to the treasury and wires it. The buy returns only once the curve reads Graduated; any failure along the way rolls back the whole buy, payments and burns included, and the curve stays Active. The public graduate(id) entry cannot graduate an Active curve early. The details are on graduation.

After graduation​

The token trades in its v4 pool on the shared hook, taxed in stock on both sides, with a 0.20% pool fee. The curve refuses trades with Closed(); claims accrued on it remain claimable. The treasury is live: income is booked, the strategy runs through execute(), and buyback() spends the buy-back budget. Nothing graduates a second time and nothing migrates.

statetrading venuewho holds the stockwhat the treasury does
Activethe curvethe curve's reservenothing; health() is (false, 0)
Readynone, transientin transferbeing wired
Graduatedthe v4 pool70% the vault, 30% the treasuryruns its strategy

Bonding curve​

The curve is a constant-product market quoted in the listed stock. A virtual stock balance gives it a nonzero opening price, and the real reserve starts at zero: buyers fund it.

Formulas​

S is the supply, V the virtual stock, T the token inventory the curve accounts for.

V = ceil(openPriceE18 × S / 1e18) virtual stock, from the listing's opening price
K = S × V fixed product
Y = ceil(K / T) effective stock at inventory T
R = Y − V real stock reserve
Tmin = floor(S × (10000 − 7931) / 10000) inventory at the end of the sale: 206,900,000 tokens
Yg = ceil(K / Tmin) effective stock at the end
Rg = Yg − V = V × 7931 / 2069 the raise, about 3.833 × V
  • Terminal price: Yg / Tmin = opening price × (10000 / 2069)² ≈ 23.36 × opening price. An opening FDV of $2,140.38 ends near $50,000.
  • Both sides of a trade round to ceil(K / T); a round trip cannot harvest an integer surplus.
  • A buy is capped at the gross payment whose net principal reaches Rg; the unused part is returned in stock.
  • Sells return stock net of tax. Virtual stock is never spendable. Transfers to the curve move nothing: no quote, no reserve, no progress.

The sale share​

79.31% of supply is sold on the curve. The share is a constructor argument of CurveDeployer (DEFAULT_SALE_BPS = 7931) and setCurveConfig refuses any other value, so no creator, owner or later transaction can move it. A stock's raise is therefore set by its listing alone. The remaining 20.69% of supply goes into the two locked pool positions at graduation.

Fees on the curve​

Every curve buy and sell pays the creator's tax in stock, split protocol 30% / creator up to half / treasury the rest, as claims inside the curve. Only the opening-window premium burns tokens. The sale allocation counts gross tokens, so an opening burn counts toward the 79.31%.

Reading it​

viewmeaning
status()0 Active, 1 Ready, 2 Graduated
realStockReserve(), terminalStock()progress toward Rg
tokenReserve(), minTokenReserve()unsold inventory and Tmin
virtualStock(), invariant()V and K
quoteBuy(maxStockIn), quoteSell(tokenIn)quotes; getting a quote

Opening window​

For the first snipeSeconds of a launch the curve's buy rate starts at snipeBps (99%) and falls in a straight line to the creator's tax. The creator chooses the window, 0 to 180 seconds; the default is 3. The premium over the tax burns tokens from the buyer's output; the tax itself is stock income.

rate(t) = taxBps + ceil((snipeBps − taxBps) × (snipeSeconds − t) / snipeSeconds) for t < snipeSeconds
rate(t) = taxBps afterwards
burn = floor(grossTokens × (rate − taxBps) / (10000 − taxBps)) tokens, from the buyer's output
  • At 99% / 3 s and a 10% tax: 99%, 69.34%, 39.67%, then 10%. At 15%: 99%, 71%, 43%, then 15%.
  • Over a 60-second window: 54.5% at 30 s and 11.49% at 59 s. Over 180 seconds: 98.51% at 1 s and 10.5% at 179 s.
  • snipeSeconds = 0, or snipeBps ≤ taxBps: the flat tax from the first second.

The chain makes a block every 0.1 s. Without a window the opening is a latency race; with one it is a falling-price auction, and a buyer who waits a second pays a lower rate than one who races for the first block.

Exemptions​

The creator is exempt from the premium automatically. Before launch the creator may freeze up to 40 more exempt recipients with CurveDeployer.setOpeningTaxExemptions(symbol, nonce, recipients); the curve emits OpeningTaxExemptionsFixed at launch. Exempt recipients still pay the base tax. quoteBuyFor(amount, recipient) quotes for a specific recipient; buyRateBpsFor(recipient) gives their live rate.

What has no window​

  • The sell side: no window and no spike, ever.
  • A graduated pool: registerGraduatedWithVault refuses a window, so the pool's buy rate is the flat tax from its first swap. hook.buyRateBps(poolId) and hook.sellRateBps(poolId) both return the tax.
  • A buy-back: v2 freezes spikeBps at 0, so a treasury buy-back does not raise the sell rate afterwards.

Graduation​

Graduation is the end of the curve and the start of the pool and the treasury. It happens inside the buy that lifts the real reserve to Rg, in that buyer's transaction, with no vote and no delay.

The split​

lpStock = floor(Rg × lpBps / 10000) the vault's stock budget; lpBps is 7000 by default
treasuryStock = Rg − lpStock sent to the treasury as its strategy capital

lpBps is a per-stock value in V2TreasuryDeployer (default 70%, floor 10%), part of a launch's terms, and frozen per treasury at launch (lpBpsOfTreasury). The vault refunds any unused stock budget to the factory, which forwards it to the treasury.

The two positions​

The factory initialises the pool at the curve's terminal price and the vault seeds two positions it owns:

positioncontents
full range, salt 0the stock budget and about Tmin × floor(Rg / 2) / Yg tokens (about 8.20% of supply at the reference setting)
single-sided, salt 1the remaining tokens (about 12.49% of supply), from the next usable tick on the token side of spot to the usable extreme
lockedSeedTokensrounding leftovers; neither refundable nor fee income

The vault has no function that removes liquidity, makes an arbitrary call or upgrades. That is the lock. The pool's spot at graduation equals the curve's last price, so the price does not jump. Graduation burns no tokens: Graduated keeps its ABI and emits 0 in tokenBurned, and GraduationCapitalSplit(id, lpStock, treasuryStock, treasuryBooked) reports the amounts and whether the treasury could book its stock at once.

The treasury's capital​

30% of the raise arrives at the treasury and wire() activates the strategy. If the market is open and the feed is fresh, the stock is booked at once; otherwise it waits as unbookedStock() until anyone calls book(). The treasury records the terminal price as its first buy-back anchor, so a young observation ring cannot hand the first buy-back a manipulated spot.

If a step fails​

Any failure inside the graduation, a seed the pool refuses, a transfer the stock issuer blocks, a callback that reverts, rolls back the entire crossing buy, payments and burns included. The curve stays Active and keeps trading. A raise larger than the stock's V3 pool can deliver can never graduate; the listing check on stock pairs exists to refuse such listings before launch.

Stock pairs​

Every launch is paired with a tokenized stock the factory owner has listed. The listing fixes three things a creator cannot substitute: the stock's PriceOracle, the stock/USDG Uniswap V3 pool the treasury trades on, and the opening price.

listings(stock) → (oracle, v3Pool, openPriceE18, enabled)
listingGates(stock) → (maxDeviationBps, maxSlippageBps, sellChunkUsdg)
bandCeiling(stock) → the most staleness band a creator may choose

The oracle​

One PriceOracle per stock: the Chainlink RHxxx / USD feed divided by the USDG feed, with the trading calendar and the staleness rules of the three prices. Feeds are 24/5; oraclePaused() is true during a corporate action. The health gate on the treasury page reads it.

The pool​

The treasury trades only on the listing's stock/USDG V3 pool, and the health gate reads only that pool. A deep pool against another asset does not qualify. Listing therefore follows depth on V3.

The opening-price rule​

openPriceE18 = floor(openingFdv × 1e18 / (price × 1e9))
openingFdv = 50,000 × 2069² / 1e8 = $2,140.38
price = the oracle's live tryPrice(), USDG per stock, 18 decimals

So every listing opens at a $2,140.38 FDV, raises about $8,205 and graduates near $50,000. The owner sets it on a market day with a fresh feed. The opening FDV drifts with the stock afterwards; re-listing recalibrates it for future launches only.

Gates and shares​

inputrelease value
lpBps7000 by default; setLpBps(stock, bps) only to deviate, 1000 to 10000
maxDeviationBps50; 125 on a 1% pool
maxSlippageBps100
sellChunkUsdg2,000 USDG, or at most the chunk the listing check prints for a 0.05% pool
bandCeiling0 unless the owner sets one; a creator's band is 0 to the ceiling

The listing check​

tools/v2_launch_check.py --factory <factory> --stock <T> runs on a fork at a recent block, on a market day, before every listing and again before a first launch. It confirms the pool can deliver the raise and that the raise does not push the pool past the deviation gate.

Day-one candidates at block 81,045,661 (2026-10-05, US session), with the release rule: 18 of 24 passed: NVDA, SPCX, CRCL, GOOGL, AMZN, GME, META, MSTR, MU, AAPL, QQQ, MSFT, TSLA, USO, GLD, SGOV, SPY, DELL. PLTR and SLV missed the deviation gate by a few basis points, INTC and AMD by more; USAR and TSM have pools too thin for the raise. Those are one block's numbers; the check runs again before each listing, and the listed set is read from listings(stock).