Integrating
Everything on Eden is read from and written to the chain. You do not need Eden's app to launch, trade, score or claim. This page covers the calls an integration needs. Addresses are on Contracts.
Eden's source code is closed for now. This page is the public interface: the function signatures, events and errors an integration needs.
Buying and selling on the curve
Each launch has its own EdenV2BondingCurve. Find it from the factory:
IEdenV2LaunchFactory.LaunchedToken memory l = factory.getLaunchedToken(token);
// l.curve, l.pairToken (address(0) = ETH), l.phase, l.graduationThreshold// ETH pair: send exactly quoteIn as msg.value
curve.buy{value: quoteIn}(quoteIn, minTokensOut, recipient);
// ERC-20 pair (USDG, stocks): approve the curve, send no value
curve.buy(quoteIn, minTokensOut, recipient);
// Sell: approve the curve for the launch token
curve.sell(tokensIn, minQuoteOut, recipient);- Fees are always taken in the pair asset.
buyon a curve that is close to selling out is partially filled and the excess refunded in the same transaction (CurveBuyRefunded).minTokensOutis then enforced as a price bound, not a quantity bound.sellreverts withCurveGraduatedonce the curve has sold out, even before the pool exists. Route to the pool, or finish graduation yourself (below).
Paying with something else
EdenV2ZapBuy swaps into the pair asset and buys in one call. It always delivers to msg.sender.
zap.buyWithEth{value: amount}(curve, route, minQuoteOut, minTokensOut, deadline);
zap.buyWithToken(curve, payToken, amountIn, route, minQuoteOut, minTokensOut, deadline);
zap.buyWithTokenPermit(curve, payToken, amountIn, route, minQuoteOut, minTokensOut, deadline, /* permit */ ...);
zap.sellForAsset(curve, tokensIn, minQuoteOut, route, minOut, deadline);route is a list of hops (venue v3/v4, tokenOut, fee, tickSpacing, hooks). An empty route means
"pay or receive the pair asset directly".
Getting a quote
The curve has no quote function. Quote off-chain from public state with the same integer math the curve uses:
// Q includes the phantom reserve and excludes fees waiting for a sweep
const [Q, Y] = await curve.getReserves();
const feeBps = await curve.feeBps();
const taxBps = await curve.creatorTaxBps(); // 0 on every Eden launch
const snipeBps = await curve.currentSnipeTaxBps(); // 0 after 15 s
const sellable = await curve.sellableTokens();
const bps = (x, b) => (x * b) / 10_000n;
// buy
const net = qIn - bps(qIn, feeBps) - bps(qIn, taxBps) - bps(qIn, snipeBps);
let out = (net * Y) / (Q + net);
if (out > sellable) out = sellable; // partial fill; the rest is refunded
// sell
const gross = (tIn * Q) / (Y + tIn);
const quoteOut = gross - bps(gross, feeBps) - bps(gross, taxBps);- Which reserves. Always price against
getReserves(), never the raw token balances. Balances include fees waiting for a sweep. - Buys and sells are not symmetric. The fee is taken from the input on a buy and from the output on a sell.
- Snipe window. During the first 15 seconds
currentSnipeTaxBps()changes every second. Quote at the timestamp you expect to land. - When to stop quoting the curve. When
readyToGraduate()is true orphase != NotGraduated, quote the Uniswap v4 pool instead.
Graduation
factory.graduate(token); // sweep + seed + lock, if the curve has sold out
factory.createGraduatedPool(token); // finish a launch left in the Swept phaseBoth are permissionless. phase moves NotGraduated → Swept → PoolCreated (Rescued only in the rare
recovery path; see Graduation).
graduationGuardActive(token) is true during the first block after seeding, when one address can take at
most 1 % of the seeded tokens.
Reading state
| Read | Returns |
|---|---|
factory.getLaunchedToken(token) | Curve, pair asset, creator recipient, threshold, phase, swept amounts |
factory.canLaunch(addr) | Whether addr can launch right now |
curve.getReserves() · realQuoteReserve() · sellableTokens() | Live curve state |
curve.phantomQuote() · graduationThreshold() · feeBps() | Fixed launch terms |
curve.currentSnipeTaxBps() | Snipe tax a buy would pay now |
launchAndBuy.devBuyVestOf(token) | The creator's vesting lock and terms |
pairs.isPairApproved(asset) | Whether an asset can be a pair |
scorerRewards.pendingRewards(token, asset, scorer) | A scorer's claimable amount |
feeEscrow.balanceOf(addr) · balanceOfToken(addr, asset) | Creator fees claimable |
Progress to graduation is realQuoteReserve() / graduationThreshold().
Launching
Launch through EdenV2LaunchAndBuy, the only path that includes the mandatory creator buy:
launchAndBuy.launchAndBuy{value: devBuyQuoteIn /* ETH pair only */}(
params, // name, symbol, logo, description, socials, creatorFeeRecipient, salt, expectedEconomics …
launchConfigId, // 0
pairToken, // address(0) for ETH
devBuyQuoteIn, // must buy 20–80 % of supply
minTokensOut,
vestTerms, // kind, duration (30 d – 4 y), cliff, release interval
extraSnipeExemptions,
creatorBuybackBps // 0–9,000, fixed forever
);- Approve ROOT to the
LaunchBurnGatefirst. The allowance is the most you can be charged for the $500 burn. Quote it withlaunchBurnGate.quoteLaunchBurn(). - Pin the terms. Read
factory.previewLaunchEconomics(launchConfigId, pairToken)and pass it asparams.expectedEconomics. If the terms change before your transaction lands, it reverts withLaunchEconomicsMismatchinstead of launching on terms you did not sign. - Addresses are deterministic. The curve and token are deployed with CREATE2 from your
salt, so you can compute them before sending (EdenV2LaunchDeployer.predictLaunchAddresses) and mine a vanity address. quoteForTokens(phantomQuote, supply, feeBps, tokensOut)tells you how much to send for a target buy.
Claiming
feeEscrow.claim(); // creator, ETH
feeEscrow.claimToken(asset); // creator, ERC-20 pair assets
scorerRewards.claim(token, asset); // scorer
holderDistributor.claim(token, asset, epoch, account, amount, proof); // anyone may submit; pays `account`
holderDistributor.claimTo(token, asset, epoch, amount, proof, recipient); // the holder redirects their own leafIn the app, Profile → Claims builds holder claims for you. Each root is posted on-chain with its snapshot block and eligible supply, so anyone can rebuild the tree.
Creator fees reach the escrow only after a sweep (curve.sweepFees, or the hook's sweep after graduation),
which Eden's keeper runs about every 6 hours.
Events to index
| Contract | Event | Use |
|---|---|---|
| Factory | TokenLaunched(token, curve, deployer, pairToken, launchConfigId, graduationThreshold) | New launch |
| Factory | PoolGraduated(token, positionId, tokenAmount, pairTokenAmount) | Graduation |
| Factory | GraduationGuardWindowOpened · GraduationGuardAcquisition | First-block guard |
| Factory | CreatorFeeRecipientChangeProposed · CreatorFeeRecipientUpdated | Fee recipient changes |
| Curve | CurveBuy(buyer, recipient, quoteIn, tokensOut, fee, tax) · CurveSell(…) | Curve trades |
| Curve | SnipeTaxCharged(buyer, amount, bps) · CurveBuyRefunded(buyer, refund) | Opening tax, partial fills |
| Curve | FeesSwept(protocol, buyback, creator) · CreatorRampApplied(paidBps, withheld, redirected) | Fee sweeps |
| Hook | HookFeeCollected(poolId, currency, fee, tax) · PoolFeesSwept | Pool fees |
| Uniswap v4 | Swap on the graduated pool | Pool trades |
| LaunchBurnGate | LaunchBurn(token, creator, amountBurned, usdValueWad, priceWad) | Launch burns |
| HumanScoreRegistry | ScoreSubmitted(epoch, token, scorer, scoreDelta, stake, burned) | Human scores |
| ScorerRewards | ScoreOpened · QualityProven · Funded · Claimed · PositionEnded | Scorer rewards |
| HolderDistributor | RootPosted · Claimed · RolledForward | Holder payouts |
| FeeEscrow | TokenCredited · NativeCredited · TokenClaimed · NativeClaimed | Creator balances |
Errors
The errors an integration is most likely to show a user:
| Error | Meaning |
|---|---|
SlippageExceeded(actual, minimum) | The price moved past your bound. Re-quote |
CurveGraduated() | The curve has sold out. Trade the pool, or call graduate |
LaunchEconomicsMismatch(expected, actual) | Launch terms changed since you signed. Re-read previewLaunchEconomics |
PairTokenNotApproved() | That asset cannot be used as a pair |
NativeValueMismatch(sent, expected) | ETH sent does not match the amount |
UnexpectedNativeValue() | ETH sent to an ERC-20-paired launch |
NotWhitelisted() | New launches are paused, and this address is not allowed |
BurnExceedsMax(required, maxBurn) | The ROOT burn costs more than your allowance or cap. Re-quote |
DevBuyRequired() · DevBuyBelowMinimum · DevBuyAboveMaximum | The creator buy is missing or outside 20–80 % of supply |
DurationBelowFloor · DurationAboveMax | The vesting length is outside 30 days – 4 years |
TimelockNotElapsed · TimelockExpired | A creator recipient change was executed too early or too late |
InsufficientOutput(out, minOut) | A zap hop returned less than its bound |
Expired() | The zap deadline passed |
NothingToClaim() | No scorer rewards to claim yet |