Some functionality will be degraded until the official mainnet launch on the 9th.
Documentation
Guides

Launching a token

There are two ways in, and they differ only in whether the creator buys in the same transaction.

factory.launchTokenlaunchAndBuy.launchAndBuy
Opening buynonerequired, quoteIn must be non-zero
Native HYPE msg.valueexactly launchFee()launchFee() + quoteIn
ERC-20 quotemsg.value is the feemsg.value is the fee; approve the router for quoteIn
Returnstoken(token, tokensOut)

Use launchAndBuy if the creator wants tokens at all. A separate buy afterwards is a race against everyone watching the chain, on a pool that opens at its lowest price.

launchAndBuy needs the router to be the factory's launchForwarder. It can be switched off in an emergency, so check GET /v1/protocol → launchAndBuy.enabled before offering it. Plain launchToken keeps working either way.

TokenParams#

FieldRule
name1 to 31 bytes, no NUL byte. Immutable
symbol[A-Z0-9], 1 to 6 characters, unique across Tartarus. Immutable
logoAt most 512 bytes. A URL, not image data
descriptionAt most 2,048 bytes
socialstwitter, telegram, discord, website, farcaster; each at most 256 bytes, may be empty
creatorFeeRecipientZero means the caller. HOLDER_REWARDS means the token's holders. Anything else is used as given
creatorFeeBpsYour tranche in basis points, inside the hook's bounds: 50 to 950 today
expectedEconomicsFrom previewLaunchEconomics. Zero waives the check
saltA random 32 bytes. See below

All limits are in UTF-8 bytes, not characters, so an emoji in a name costs four.

creatorFeeBps has no default worth relying on. Leaving it at zero is outside the bounds and reverts CreatorFeeOutOfBounds, so a launch can never land on a rate nobody chose.

The ticker#

Symbols are unique because HyperCore tickers are. Whoever lands first owns the ticker for good. These are reserved and can never be used: HYPE, USDC, USDT, USDE, USDH, PURR, BTC, ETH, SOL, UBTC, UETH, USOL, HFUN. The owner can reserve more.

Check before you show a form:

$ ts
const free = await client.readContract({
  address: FACTORY, abi: factoryAbi, functionName: "isSymbolAvailable", args: ["MINE"],
});

GET /v1/launch/symbol?symbol=MINE gives the same answer with a reason: ok, invalid, reserved or taken.

The salt and the token address#

The token address is CREATE2, salted with keccak256(abi.encode(deployer, salt, creatorFeeRecipient, creatorFeeBps, launchConfigId)), and the metadata is part of the creation code. So:

  • your salts are your own, and nobody can land a launch at an address derived from your account;
  • an address commits to exact terms, so a vanity salt only works for the recipient, tranche, config and metadata it was mined for.

Do not compute the address by hand. Call deployer.predictLaunchAddress, or POST /v1/launch/predict with a session, which also returns the pool key and floor price so you can draw the token before it exists.

For a holder-rewards launch, use a fresh salt every time. A distributor's address depends only on creator, salt and quote, so reusing one reverts HolderRewardsDistributorTaken.

expectedEconomics#

The digest is:

$ solidity
keccak256(abi.encode(quoteToken, startingTick, tickSpacing,
                     protocolFeeBps, creatorFeeBps, maxInternalPriceImpactBps, launchFee))

previewLaunchEconomics(configId, creatorFeeBps) computes it. If any input moves between your read and your transaction, the launch reverts with LaunchEconomicsMismatch(expected, actual).

Metadata cannot be fixed later#

Everything on the token is permanent. The contract has no setter, and the name and symbol must never change because Elysium's bridge keys a token's mirror on them. Check spelling, the ticker and the logo before you sign.

What can change is creatorFeeRecipient: the current recipient can hand it on with factory.transferCreatorFeeRecipient(token, newRecipient). The creator tranche itself is frozen.

Common reverts#

ErrorMeaning
NotWhitelisted / NotApprovedLauncherLaunching is closed and you are not whitelisted
IncorrectLaunchFee / WrongValuemsg.value is not exactly right. Re-read launchFee()
LaunchConfigDisabled / InvalidLaunchConfigIdThat config is off or does not exist
QuoteTokenNotApprovedThe config's quote is no longer approved
InvalidName / InvalidSymbol / MetadataTooLongA TokenParams rule above
SymbolReserved / SymbolTaken(address)The ticker is unavailable
CreatorFeeOutOfBounds(bps, min, max)Your tranche is outside the bounds
LaunchEconomicsMismatch(expected, actual)Terms moved. Re-read and show the user the new ones
RewardsFactoryNotSetHOLDER_REWARDS used before the rewards factory was wired
HolderRewardsDistributorTaken(address)Salt reused for holder rewards. Use a new one
ZeroBuylaunchAndBuy with quoteIn of zero. Use launchToken

CreatorFeeOutOfBounds comes from the hook, so a client holding only the factory ABI sees the raw selector 0x87ab5572. Decode with the combined tartarus.json from the ABI page, or look any selector up on the Errors page.

POLLINGElysium · 99901 · Mainnet
--:--:-- UTC