GRAIL
Launches

Token launches

How one transaction creates a token, its Uniswap pool and its locked liquidity, and how the launch price and launch guard work.

What createToken does

createToken(name, symbol, metadataURI, feeRecipient, minTokensOut) payable
  1. 1
    Takes the launch fee. It is fixed at deployment at 0.002 ETH. Any ETH above it is the creator's first buy.
  2. 2
    Deploys the token. Each token is a small EIP-1167 clone at a CREATE2 address, so its address is known in advance. The clone mints the whole supply of 1,000,000,000 to the launchpad.
  3. 3
    Prepares the pool. It creates the token's 1% Uniswap v3 pool and sets the launch price. If someone created that pool first, it moves the price to the launch price with a 1-wei swap, which works only through empty ranges. Any liquidity in the way reverts the launch.
  4. 4
    Adds the liquidity. It mints one position with the whole supply, single-sided, from the launch price to the edge of the range. The position belongs to GrailLocker. Rounding dust is burned.
  5. 5
    Runs the first buy. Any remaining ETH is swapped in the pool for the creator, with minTokensOut as protection. Unused ETH is refunded.

The launch is one transaction. Either all of it happens or none of it does. On a mainnet fork it uses about 5.5M gas, so its cost depends strongly on the gas price at that moment.

The token

A GrailToken is a fixed-supply ERC-20 with no owner, no mint function and no tax. It has one extra rule, the launch guard, which ends after its first few blocks. Nobody but the launchpad can initialize a clone, and only in the transaction that creates it.

Where the price comes from

Nobody deposits ETH to start a pool. It holds only the token's own supply until people buy, and the pool's ETH comes only from buyers. The start market cap is a deployment parameter, launchTick, a multiple of 200:

launchMarketCap = 1,000,000,000 × 1.0001^launchTick (in WETH)

price after s tokens are sold = P0 × N² / (N − s)²

That is the same shape as a virtual-reserve bonding curve with the whole supply on it, except that it lives in a standard Uniswap pool. There is no graduation and no migration. The position starts exactly on the tick, so the first buyer pays exactly the configured price. With a tick of −195,400, the start is 3.27 ETH:

Share of supply soldETH in, before feesPrice against the startMarket cap
10%0.36 ETH1.23×4.03 ETH
50%3.27 ETH4×13.07 ETH
80%13.07 ETH25×81.7 ETH
90%29.4 ETH100×327 ETH

The market cap is set in ETH, so its dollar value moves with the ETH price.

Locked liquidity

GrailLocker holds every position and has no path to withdraw one. It can do only one thing with a position: collect its fees and split them. Nobody can pull the launch liquidity, including the creator, the owner and Grail.

The launch guard

For the first 5 blocks, about a minute, the token caps the net number of tokens leaving its pool at 1% of supply per block, across all buyers. That stops one wallet from taking a large share of the supply in the opening blocks.

  • Tokens sold back into the pool in the same block free the allowance again, so a flash loan or a round trip cannot use up the block and lock others out.
  • A buy above what is left reverts. The app explains this and suggests a smaller amount.
  • Sells and transfers between holders are never limited.
  • The creator's first buy is not limited by the guard. It passes through the launchpad and is shown on the token page.

Blocked launches

A launch is visible in the public mempool. Anyone who sees it can compute the token's address, create its pool and place liquidity in the way, and the launch then reverts with PoolManipulated. That costs the attacker about 5M gas and the creator about 0.5M gas.

The creator has nothing to do about it. The app simulates each launch before signing and picks a new address if the pool is blocked. After a blocked launch it retries automatically, up to three times, with a new address each time.

Private buys at launch

Because the token's address is known in advance, the browser can build a private buy before the launch and send it right after. On Sepolia the launch landed in block 12041351 and the private buy in the next. The app warns that a private buy in the first blocks may be guessed to be the creator's.

Token data

The image and description are uploaded when the token is created. They are checked, converted and stored under their content hash on Grail's server, and the token stores the resulting public link, readable with metadataURI(). It can never change. The file is a small JSON document with name, symbol, description, image, x, twitter, telegram and website. These files are not on IPFS, so they depend on that server. The token, its pool and the fees do not.

Grail is an independent project built on Railgun's public contracts and SDK. Railgun contributors do not run, review or endorse Grail, and they did not write this documentation. Their own documentation is at docs.railgun.org.