Documentation
Launching a token
Two entrypoints, and the right one depends on whether there is an opening buy.
factory.launchToken | launchAndBuy.launchAndBuy | |
|---|---|---|
| opening buy | none | required, non-zero |
| approve | the factory, launchFee() | the router, launchFee() + quoteIn |
creatorFeeRecipient zero | defaults to the caller | rejected |
| creator's starting balance | nothing | the opening buy |
launchAndBuy reverts with ZeroAmount on a zero quoteIn — it exists to make
deploy-and-buy atomic and refuses to be used as a plain deployer.
TokenParams#
struct TokenParams {
string name; // required, <= 64 bytes
string symbol; // required, <= 16 bytes
string logo; // <= 512 bytes — a URI, never the image
string description; // <= 2048 bytes
Socials socials; // five strings, each <= 256 bytes
address creatorFeeRecipient; // earns the creator split and the whole creator tax
uint16 creatorTaxBps; // extra tax on top of the curve fee, capped by maxCreatorTaxBps
bytes32 expectedEconomics; // terms pin; bytes32(0) waives it
bytes32 salt; // CREATE2 salt, namespaced per account
}Three of these deserve attention.
logo is a reference, not an image#
It is stored on-chain, so it must be short. Putting a base64 data URI here does not merely cost gas — the node rejects the transaction outright and the launch never reaches the contract. Upload the image first and store the resulting URL.
expectedEconomics#
A digest of the exact terms this launch will lock in. Get it from
previewLaunchEconomics(launchConfigId, pairToken) in the same flow as the submit.
It covers the phantom reserve, graduation threshold, supply, curve fee, pool fee, tick
spacing, the protocol fee shares — and the launch fee. So an owner calling
setLaunchFee between your quote and your signature invalidates it, and the launch reverts
with LaunchEconomicsMismatch(expected, actual) rather than landing on terms your user
never saw.
Do not cache it. bytes32(0) waives the check entirely, which means accepting whatever is
live when the transaction lands.
salt#
A raw CREATE2 salt, namespaced by the factory as keccak256(deployer, salt) — so it only
needs to be unique among your own launches. Two creators may use the same value.
Reusing one on otherwise identical terms reverts with FailedDeployment, which says nothing
about salts. Call launchDeployer.predictLaunchAddresses(...) first to check for existing
code, and to mine a vanity address if you want one.
Preconditions worth checking before you show a form#
const canLaunch = await read("canLaunch", [account]); // false by default on a new deployment
const fee = await read("launchFee"); // may be zero -> no approval needed
const economics = await read("pairTokenEconomics", [USDC]); // phantom + threshold, in 6 decimalslaunchEnabled is left false by deployment, so a fresh environment rejects every launch
until the owner opens it or whitelists an address. Surfacing that as a disabled button beats
a revert.
Common reverts#
| Error | Cause |
|---|---|
NotWhitelisted / NotApprovedLauncher | launching is closed for this address |
LaunchEconomicsMismatch | terms moved between quote and submit |
FailedDeployment | this account already used that salt |
CreatorTaxTooHigh | creatorTaxBps above maxCreatorTaxBps() |
PairTokenNotApproved | the quote asset is not approved by the owner |
ZeroAmount | zero quoteIn on the router path — use launchToken |
| ERC-20 allowance revert | approved the wrong contract; see Approvals |