Skip to content
montra

For builders

Contract reference

What each part of Montra does, function by function, with each signature's types, the structs a read returns field by field, and the arithmetic behind the figures the other pages show.

Fees in pips
1,000,000
Is 100%, of the quote leg.
Pool fee field
0x800000
Dynamic: the LP fee lives in the pool's slot0.
Tick spacing
200
On every published tier.
Hook flags
0x38EC
The low 14 bits of the hook's address.

The ABIs

Every contract's ABI is published from the contracts' build: /docs/abis.json for all of them, one per contract at /docs/abis/<Contract>.json, and every event once at /docs/abis/events.json (the list, and reading them with a header, under Build on Montra). The types below are the ABI's: a pool id is bytes32, a currency address (native HYPE is the zero address), a struct a tuple by its name.

Launching · LaunchFactory

LaunchFactory.launchSolidity
// in this order, which is the ABI's: selector 0x579ba2d5
LaunchFactory.launch(LaunchParams {
  string    name;
  string    symbol;
  string    metadataURI;
  Profile   profile;         // logo, description, socials { telegram, twitter, discord, website, extra }
  uint256   configId;        // a published tier for one quote asset; ids count from 0
  uint256   supply;          // whole tokens × 1e18; 0 = the config's 1e9
  bytes32   salt;            // token address = clone(keccak256(abi.encode(msg.sender, salt)))
  address[] feeRecipients;   // see "The creator's routes"
  uint16[]  feeShares;
  uint256   firstBuyAmount;
  uint256   firstBuyMinOut;
  Permit    permit;          // deadline, v, r, s: an optional EIP-2612 for an ERC-20 first buy, all zero for none
}) payable returns (address token, PoolId poolId)
  • Reads. configCount() view returns (uint256), getConfig(uint256 id) view returns (LaunchConfig cfg), getModuleSet(uint256 id) view returns (ModuleSet mods) (hook, tokenMaster, splitterMaster, exists), launchFee() view returns (uint256), launchEnabled() view returns (bool).
  • Value. For a native-quoted tier msg.value is the launch fee plus the first buy; for an ERC-20 quote it is the launch fee alone and the first buy is pulled from the caller.
  • The creator is msg.sender. The token is an EIP-1167 clone at an address derived from the sender and the salt (predictTokenAddress(address sender, bytes32 salt, uint256 configId) view returns (address)), so nobody can take a pending address or pin a token on a wallet that never signed.
  • Order in the transaction. Clone and mint the supply to the hook; resolve the fee route (deploying a splitter for a split); hook.register; PoolManager.initialize at the opening tick; hook.seed; token.initializePool (pool id and reward terms); the first buy; TokenLaunched.
  • Opening price. Each tier is published for a base supply of 1e9 tokens at a start tick. A different supply shifts the tick by log(supply / 1e9) / log(1.0001), rounded to the tick spacing of 200, so the opening market cap stays the same to within about 1%. LaunchLens.seedPreview(address factory, uint256 configId, uint256 supply) view returns (int24 startTick, Seed seed) checks a custom supply before launching (its Seed is (int24 tickLower, int24 tickUpper, uint128 liquidity)).
  • Quote assets. QuoteRegistry lists them (QuoteRegistered, QuoteEnabled), six to eighteen decimals; native HYPE is listed from the start. Disabling a quote stops new launches in it; a pool's quote never changes. A Montra launch token is never listed.
  • Reverts. Among them: LaunchesPaused, ConfigDisabled, InvalidConfigId, QuoteNotEnabled, IncorrectValue, FirstBuySlippage, SupplyOutOfRange, SupplyNotWholeCoins, InvalidFeeRoute, InvalidFeeRecipient; a split's recipients and shares are checked by the splitter (InvalidRecipients).

The token · LaunchToken

  • A clone that cannot change. Each token is an EIP-1167 clone of one master whose address is fixed in the clone's bytecode; the master locks itself against initialization. There is no proxy admin and no upgrade path.
  • Verifying a token. Compare its code hash with a clone of the master the factory published (ModuleSetPublished). Anyone can clone a master, but only the factory it names can initialize one, so a clone with a supply is a launch.
  • Metadata. One URI, fixed at launch, answers contractURI(), tokenURI() and metaURI(), each returns (string) (ERC-7572; there is no tokenURI(uint256)). The profile, also fixed, answers logo(), description() (string), socials() (Socials) and getTokenInfo() returns (address creator_, string logo_, string description_, Socials socials_), Socials being (string telegram, string twitter, string discord, string website, string extra), its outputs named as here, underscores included. deployer() returns (address) is the creator under another name. The strings are stored as the launcher sent them: bound and escape them, and render only http(s):// and ipfs:// links.
  • The metadata document. A launch through Montra's site names an ipfs://<cid> document whose JSON has name, symbol and description (strings), attributes (an array of { "trait_type": string, "value": string }: launch_provider: montra and chain: elysium) and, where given, image (ipfs://<cid>, the same string as logo()), website (also as external_url), twitter, telegram and discord (links). A launch sent to the factory by other means may name anything, so prefer the on-chain profile. To give a launch of your own its image the same way, see Launch a token. Read ipfs:// through a gateway that serves it: https://ipfs.filebase.io/ipfs/<cid> does; ipfs.io and dweb.link answer 429 to most requests and w3s.link redirects, so use filebase or your own.
  • Tax surface. Each direction its own, read live from the hook, in basis points rounded up. sellTaxRate() and taxBps() (under the name many terminals already read) return the pool's total fee, which a sale always pays, and taxRatePips() the total's exact figure; buyTaxRate() returns what a buy pays now, the total, or inside the pool's anti-snipe window the higher rate falling to it. It is the pool's fee on the quote leg, not a token tax: transfers between wallets pay nothing.
  • Also readable. creator(), hook(), custodian() and factory() (each address), poolId() (bytes32), decimals() (18), burn(uint256 amount); launchBlock() (uint256) is the launch's block.number, which on an Arbitrum chain is the parent chain's block, so take the chain's own from the TokenLaunched log.
  • Gas. A transfer between two wallets costs about 47k gas once both are settled, and up to about 170k the first time two wallets earning holder rewards settle mid-stream (the contracts' gas snapshot). Do not hard-code transfer gas.

The pool and its lines · LaunchHook

  • The pool. A Uniswap v4 pool with the dynamic-fee flag (fee = 0x800000), tick spacing 200 and the launch hook. Only the factory can create a pool on the hook (beforeInitialize refuses anyone else), and only one it registered.
  • The seed. One position, owned by the hook: from the opening tick to the highest usable tick when the token is currency0, from the lowest usable tick to the opening tick when it is currency1. Either way it holds only the token. Its liquidity is rounded down so the pool never asks for more tokens than exist; the remainder is burned (PoolSeeded(poolId, tickLower, tickUpper, liquidity, dustBurned)). The hook never calls modifyLiquidity with a negative delta for its own position, and has no function that could.
  • The seed's fees. harvestSeed(poolId), which anyone can call and claim runs first, collects them with a zero-delta poke: the quote side to the creator side's balance, the token side burned (SeedFeesHarvested).
  • Outside liquidity. beforeAddLiquidity refuses an add only before the pool is seeded, when its tier seals the pool, or when its tier names a liquidity policy and that policy refuses; no published tier does either. Removing has no hook callback at all, so outside liquidity can always come back out, and zero-delta pokes that collect fees work.
  • The arithmetic. With the seed as the only liquidity, the share of supply bought by a price multiple m is 1 − 1/√m, and the quote it takes is (√m − 1) × the opening market cap, before fees.
  • Where the lines are. Tick offsets from the opening, in the direction the token's price rises: graduation 28,200 ticks (1.0001^28,200 ≈ 16.77), the LP line 49,600 ticks (≈ 142.56). Placed when the pool is seeded, so a custom supply graduates at the same market cap. From a $3.5k opening, reaching them takes about $10.8k and $38.3k of buying, before fees. The dollar figures depend on each quote's opening; the multiples are fixed.
  • Stages. Below → Crossed → Graduated → LpCrossed → LpActive, in hook.poolConfig(poolId).stage. afterSwap marks a crossing (and the transaction that made it, in transient storage keyed by the pool id); the first beforeSwap of a later transaction confirms it, before that swap's fee is chosen. A sell back under an unconfirmed line uncrosses it. A pool confirmed past graduation with the price already past the LP line starts the hold there.
  • The hold and the switch. lpLineHold is immutable on each hook (600 seconds on the first; the address book reads every hook's, and LaunchLens.poolView a pool's as lpLineHoldSeconds), counted cumulatively (lpHeldSeconds plus the current stretch). On confirmation the hook calls updateDynamicLPFee(key, lpFee) once and emits LpFeeActivated(poolId, lpFee); the pool's stored LP fee is zero before and the tier's LP fee after, never changing again. Graduation emits Graduated(poolId).
  • Reads. LaunchLens.graduationProgress(address hook, bytes32 poolId) view returns (uint256) and lpLineProgress(address hook, bytes32 poolId) view returns (uint256) (basis points of the quote the seed must collect to reach the line), lpLineHeld(address hook, bytes32 poolId) view returns (uint256 held, uint256 hold) (seconds held, and the hold).

Fees · LaunchHook, LaunchLens

  • Units. Pips of the quote leg: 1,000,000 is 100%. The tiers in pips (total / floor / protocol / LP): 10,000 / 10,000 / 4,000 / 1,000; 20,000 / 11,000 / 4,000 / 3,000; 30,000 / 13,000 / 4,000 / 5,000; 50,000 / 18,000 / 4,000 / 10,000; 100,000 / 18,000 / 4,000 / 10,000.
  • The rule. The factory refuses to publish, and the hook to register, any terms outside protocol + lp ≤ floor ≤ total ≤ 100,000, with the LP line at or past graduation (FeeTerms.valid): at the floor, with the LP fee on, the creator side's remainder is never negative, and may be zero. The hook's ceiling of 10% is a constant in its code. How a floor divides beyond that is the menu's choice, not a rule: today's tiers keep the creator side at least the protocol's share at the floor, and no LP fee above 1%.
  • Hook fee and LP fee (Experimental). The hook takes total − lpFee on the quote leg, where the LP fee in force is zero until the LP line is confirmed; the pool charges the LP fee itself, on the swap's input. The two compound, so the all-in rate is h + lp − h·lp / 1e6, a hair under the advertised total once the LP fee is on: on an exact-input buy the hook's fee comes off the input and the pool charges its LP fee on the rest; on a sell the pool charges its LP fee on the token in and the hook takes its fee from the quote out.
  • The LP fee is experimental. Its rates, and the line it starts at, may change for launches to come; a pool keeps the LP fee and the line it launched with.
  • The anti-snipe fee. A row may carry one, earlyBuyFeeStartPips and earlyBuyFeeWindow. Both are zero, or the start is above the row's total and at most 990,000 (99%) and the window 1 to 1,800 seconds (FeeTerms.validEarlyBuyFee, which the factory applies at publication and the hook at registration; the hook's MAX_EARLY_BUY_FEE_PIPS and MAX_EARLY_BUY_FEE_WINDOW). The hook stamps the window from the second it registers the pool, t₀, and stores its end, earlyBuyFeeUntil = t₀ + W. A buy at second t < t₀ + W pays B = S − ⌊(S − T)·(t − t₀) / W⌋, with S the start and T the pool's total now, so the rate is rounded up, never below the line; equally, B = T + ⌈(S − T)·(t₀ + W − t) / W⌉. From t₀ + W a buy pays T. A clock behind t₀ is charged S. B never rises: a later second, or a total lowered inside the window, only lowers it, the line then running from S at t₀ to the new total at the window's end.
  • Who it pays. The hook takes B − lpFee on the quote leg, as it takes the total outside a window; the protocol's part stays its pips of the leg, and everything above goes to the creator side. A sale never pays it, and neither does the factory's own first buy in the launch transaction: the hook exempts the factory's swaps inside the transaction that registered the pool, and nothing else. It is netted into the swap's deltas, so routers and quoters charge it as they charge the rest of the fee. A quote taken in an earlier second overstates the fee, so a minimum output taken from it is looser than its percentage: The anti-snipe fee.
  • Reading it. LaunchHook.currentBuyFeeRate(bytes32 poolId) view returns (uint256), what any buy pays this second in pips; LaunchHook.currentFeeRate(bytes32 poolId, address) view returns (uint256), which stays the total, its second argument unnamed and ignored, so any address gives the same answer (the token passes zero) and the call does not encode without one; LaunchLens.poolView's buyFee and buyEffectiveTotalFee; LaunchLens.buyFeeSchedule(address hook, bytes32 poolId) view returns (uint24 startPips, uint24 endPips, uint40 startsAt, uint40 endsAt, uint24 nowPips), all zero for a pool without one. PoolRegistered carries the start and the window, the event's block time is t₀, and TotalFeeUpdated moves T: nothing is emitted when a window ends. How an app or a router reads, tracks and shows it: The anti-snipe fee.
  • Levers. lowerTotalFee(bytes32 poolId, uint24 totalFee) (the pool's recipient; strictly lower, at least the floor, not once locked) emits TotalFeeUpdated; lockFee(bytes32 poolId) emits FeeLocked; lowerProtocolFee(bytes32 poolId, uint24 protocolFee) (the hook's owner; strictly lower, the difference going to the creator side) emits ProtocolFeeUpdated. None can raise.
  • Reads. LaunchLens.feeBreakdown(address hook, bytes32 poolId) returns (uint24 total, uint24 lp, uint24 protocol, uint24 creator, uint256 effectiveTotal) for the next sale, and a buy outside an anti-snipe window, in pips; LaunchToken.taxRatePips() the total (uint256), taxBps() the same in basis points rounded up (uint24). Which to show is under Build on Montra.
  • Uniswap's own fee. Uniswap v4 can charge a protocol fee of its own on a pool if Uniswap switches one on; it would come on top of the pool's fee. LaunchLens.poolView reports it per direction (coreProtocolFeeZeroForOne, coreProtocolFeeOneForZero).

Claims and collection · LaunchHook

during the swap
The hook mints claims on the pool manager for its fee, in the quote, and books the creator and protocol parts as pending. FeeAccrued(poolId, zeroForOne, amountSpecified, fee, protocolPart) is emitted once per swap, even when the fee rounds to zero, so it pairs one-to-one with the pool manager's Swap: before it when the fee is taken in beforeSwap (the quote is the amount named), after it otherwise. amountSpecified is the swap's own, signed as v4 signs it: negative for exact input, positive for exact output, which is what chooses the fee's formula.
sweep(bytes32 poolId) returns (uint256 creatorAmount, uint256 protocolAmount)
Anyone. Redeems the pool's claims: the creator part to tab[poolId], the protocol part to protocolTab[quote]. FeesSwept.
harvestSeed(bytes32 poolId) returns (uint256 quoteToCreator, uint256 tokensBurned)
Anyone. Collects the locked seed's LP fees: quote to the tab, token burned. SeedFeesHarvested.
claim(bytes32 poolId, address to) returns (uint256 amount)
The pool's recipient only. Sweeps, harvests and pays the whole tab to to, never to address one. CreatorFeesClaimed.
claimTab(bytes32 poolId, address to, uint256 amount) returns (uint256)
The recipient only. Pays from the tab alone, without sweeping first; zero means all of it.
collectProtocol(address currency) returns (uint256 amount)
Anyone. Sends the protocol's balance in a currency to the vault. ProtocolCollected.
pendingCreator(bytes32 poolId) · pendingProtocol(bytes32 poolId)
Each returns (uint256): what a sweep would move now, of each part.
LaunchLens.creatorClaimable(address hook, bytes32 poolId) returns (uint256)
What claim would pay right now: tab, pending and the seed's unharvested quote.

The creator's routes · LaunchFactory, FeeSplitter

  • At launch. feeRecipients and feeShares: none for msg.sender; one address with share 10,000 for that address; two to four with shares summing to 10,000 for a FeeSplitter clone (FeeSplitterDeployed). HOLDERS = address(1) in any slot names the token itself, as it does for the hook's updateRecipient and a splitter's rotate; nothing is ever paid to address one (claim, claimTab, a splitter's collect and claimRewards(to) refuse it). feeLocked is true from birth when the recipient is the token or a splitter. System contracts (the factory, the pool manager, the vault, the quote, another launch's token or splitter) are refused.
  • After launch. LaunchHook.updateRecipient(bytes32 poolId, address newRecipient), the current recipient only, emits RecipientUpdated; naming the pool's own token sets feeLocked. LaunchFactory.deploySplitter(uint256 moduleSetId, bytes32 poolId, bytes32 salt, address[] recipients, uint16[] shares) returns (address), the current recipient only, deploys a splitter for that pool, which the recipient then names with updateRecipient. The hook checks neither that a splitter was made for the pool nor that the fee was lowered first.
  • FeeSplitter. Ownerless. distribute() returns (uint256 amount) (anyone) pulls the pool's claim and divides what it holds; collect(address to, uint256 amount) returns (uint256) pays a recipient its share; rotate(address to) hands on the caller's own slot, refusing the hook, the factory, the vault, the quote and other launches' tokens and splitters; recipients() view returns (address[]), shares() view returns (uint16[]), owed(address) view returns (uint256).
  • Before a handover, an interface should have the new address prove it controls the key (a signature, or ERC-1271 for a multisig): there is no accept step, and the hook cannot tell a typo.

Holder rewards · LaunchToken

  • distribute() returns (uint256 received), anyone: pulls what the pool owes the token (from the hook, or from a splitter that lists it) and starts a stream of streamDuration (3,600 seconds on every published tier), folding in what is still streaming. New money that, with anything already parked, comes to under 1% of what is still streaming is parked for a later distribution rather than delaying the current one.
  • claimRewards() returns (uint256) and claimRewards(address to) returns (uint256 amount) pay the caller everything earned, never to address one. earned(address holder) view returns (uint256) reads it. isExcluded(address account) view returns (bool) names who earns nothing: the PoolManager, the hook, the token, 0x…dEaD and address one.
  • pushRewards(address[] holders) returns (uint256 pushed, uint256 bounty), anyone: pays each listed wallet less the pusher's fee, which is pushBountyBps of the payout (25 basis points on every published tier) or pushFloor in quote units, whichever is more. The floor is zero in the mainnet configuration; a payout under PUSH_GATE (20) floors is left to accrue, so the fee never passes 5%. Only accounts with no code, or an EIP-7702 delegation, are pushed to; a holder that cannot take the payment is skipped (RewardsPushSkipped), never blocking a batch. No code includes a contract not yet deployed: a counterfactual Safe, a smart account or an escrow that holds the token before its contract exists is pushed to like a wallet, so the contract later deployed there must be able to take out and move what it was paid in the reward asset.
  • The ledger. One running index in Q128; a transfer settles only the two accounts it touches, so a distribution costs the same at ten holders or a hundred thousand.
  • Reads. LaunchLens.rewardView(address token, address holder) view returns (RewardView v), earnedMany(address token, address[] holders) view returns (uint256[] amounts); streaming() view returns (uint256 remaining, uint256 perSecond, uint256 unplaced) on the token.

The protocol's share · ProtocolFeeVault, FeeMarket, fillers

  • The vault. collectProtocol(currency) on the hook, which anyone can call, sends the protocol's balance to the ProtocolFeeVault; allocate(currency), also anyone's, divides it among the lanes by their shares: all of it the treasury's until the buyback is pointed at MONTRA, 70% the buyback's and 30% the treasury's from then on. The treasury is paid in HYPE (deliver(uint256 lane) returns (uint256 amount), anyone).
  • The fee market (FeeMarket). One standing sale per currency, never per launch or per lot: whatever has accrued is the lot, and a take may be partial. A hub sale sells for HYPE what the converting lanes hold of a currency and may sell (ProtocolFeeVault.sellable(currency)); the buyback's sales sell what its lane holds for MONTRA. The price is the keeper's reference, a rate net of every fee on the sale's route that moves only as fast as time allows, times a level that falls from just above it to the floor: 1% under it for most currencies on mainnet, 3% for memes and stock tokens, 1.5% for the buyback. A hub sale sells nothing on a reference more than 5 minutes old. How to take one is under Run a keeper.
  • Filling. The keeper fills hub sales through RouteFiller, which trades through v4 pools with a minimum rate from the keeper's own quote; anyone may fill one, through it or from their own funds, and the market is paid its price either way. What the keeper's fills make above that price goes to the protocol.
  • The buyback. BuybackFiller is the only taker of the buyback's sales and serves the keeper's keys alone. It buys MONTRA in MONTRA's own pool, the last hop of every route, and the TokenBurner destroys what it buys in the same transaction, so MONTRA's supply falls (Bought, Burned). Each of its sales releases at most a daily cap, accruing by the second, that the team's multisig sets (FeeMarket.setDrip) and its signing tools hold to 5% of the real depth of MONTRA's pool, retuned as the pool deepens: a rule of the team's, not one the contracts enforce. What arrives above a cap waits in the vault and is released at the cap on later days.

Structs and the stages

Each struct a read returns or an event carries, field by field in the ABI's order, as viem decodes it into an object and ethers into a named tuple. The pool's stage, PoolConfig.stage, is a uint8 numbered as below.

stage

0
LaunchHook.StageBelow
What it meansShort of graduation.
1
LaunchHook.StageCrossed
What it meansA swap left the price past the graduation line; the first swap of a later transaction confirms it, whichever way that swap trades. Only a sale in the same transaction returns the pool to Below.
2
LaunchHook.StageGraduated
What it meansConfirmed past graduation, for good.
3
LaunchHook.StageLpCrossed
What it meansPast the LP line, its hold counting (lpHeldSeconds, lpCrossedAt). A sell back under it returns the pool to Graduated, the time held kept.
4
LaunchHook.StageLpActive
What it meansThe LP fee is on, for good.

PoolKey: LaunchHook.poolKey(poolId), PoolView.key, Uniswap v4's own.

Field

currency0
Typeaddress
What it isThe lower address; native HYPE is the zero address.
currency1
Typeaddress
What it isThe higher address.
fee
Typeuint24
What it is0x800000, the dynamic-fee flag: the LP fee lives in the pool's slot0, never here.
tickSpacing
Typeint24
What it isThe row's tick spacing.
hooks
Typeaddress
What it isThe launch hook.

ExactIn: LaunchRouter.swapExactIn's one argument.

Field

key
TypePoolKey
What it isThe pool's key, from poolKey(poolId).
zeroForOne
Typebool
What it isTrue to sell currency0 for currency1. A buy is zeroForOne == quoteIsCurrency0.
amountIn
Typeuint128
What it isExactly what the trade spends, in the input's base units. A native input is sent as the call's value, equal to it.
minAmountOut
Typeuint128
What it isThe least the trade may deliver, or it reverts TooLittleReceived.
recipient
Typeaddress
What it isWho receives the output: never zero (ZeroAddress) or the router itself (InvalidRecipient).
deadline
Typeuint256
What it isA Unix time in seconds, after which it reverts Expired.

PoolView: LaunchLens.tokenView(token) and poolView(hook, poolId): 50 words, the key's 5 and the config's 23 inline.

Field

key
TypePoolKey
What it isThe pool's key.
config
TypePoolConfig
What it isThe pool's terms and state, as poolConfig(poolId) returns them (below).
sqrtPriceX96
Typeuint160
What it isThe pool's price now, from slot0.
tick
Typeint24
What it isThe pool's tick now.
poolLpFee
Typeuint24
What it isThe LP fee slot0 holds, in pips: zero until the LP line's switching trade has run.
activeLiquidity
Typeuint128
What it isThe liquidity in range now, the seed's and anyone else's.
totalFee
Typeuint24
What it isWhat the next sale pays, in pips, and a buy outside an anti-snipe window: feeBreakdown's total.
lpFee
Typeuint24
What it isThe LP fee the next trade pays: feeBreakdown's lp, already the tier's once the hold is done, while slot0 may still read zero.
protocolFee
Typeuint24
What it isThe protocol's absolute share, in pips.
creatorFee
Typeuint24
What it isThe creator side's rest: totalFee − lpFee − protocolFee, never negative.
effectiveTotalFee
Typeuint256
What it isThe all-in rate with the two fees compounded, h + lp − h·lp / 1e6, in pips: a hair under totalFee once the LP fee is on.
buyFee
Typeuint24
What it isWhat a buy pays now, in pips (the hook's currentBuyFeeRate): totalFee, or inside the pool's anti-snipe window the higher rate falling to it.
buyEffectiveTotalFee
Typeuint256
What it isWhat a buy pays all in: the hook's part of buyFee compounded with the LP fee in force, as effectiveTotalFee is, so equal to buyFee until that fee is on. A buy pays 1 / (1 − buyEffectiveTotalFee / 1e6) times the pool's price, before its move.
coreProtocolFeeZeroForOne
Typeuint24
What it isUniswap's own protocol fee on a zeroForOne swap, in pips: zero unless Uniswap switches it on, then charged on top.
coreProtocolFeeOneForZero
Typeuint24
What it isThe same, the other way.
pendingCreator
Typeuint256
What it isThe creator side's fees a sweep would move, in the quote.
tab
Typeuint256
What it isThe creator side's swept balance, in the quote.
harvestableQuote
Typeuint256
What it isThe seed's LP fees in the quote not yet harvested (they go to the creator side).
harvestableToken
Typeuint256
What it isThe seed's LP fees in the token not yet harvested (they are burned).
pendingProtocol
Typeuint256
What it isThe protocol's fees a sweep would move, in the quote.
graduationProgressBps
Typeuint256
What it isHow far to graduation, in basis points of the quote the seed must collect: 10,000 once past it, Crossed included.
lpLineProgressBps
Typeuint256
What it isThe same toward the LP line.
lpLineHeldSeconds
Typeuint256
What it isSeconds spent past the LP line so far, up to the hold.
lpLineHoldSeconds
Typeuint256
What it isThe hold: the LP fee starts at the next trade once the two are equal.

PoolConfig: LaunchHook.poolConfig(poolId) and PoolView.config: this generation's layout (a later hook's may differ; decode it with that hook's ABI).

Field

totalFeePips
Typeuint24
What it isThe pool's total fee now, in pips: only ever lowered, never under totalFeeMinPips.
lpFeePips
Typeuint24
What it isThe pool's LP fee, fixed; charged from the LP line on.
protocolFeePips
Typeuint24
What it isThe protocol's absolute share, only ever lowered.
exists
Typebool
What it isThe hook registered this pool.
quoteIsCurrency0
Typebool
What it isThe quote asset is currency0.
liquiditySealed
Typebool
What it isOutside liquidity is refused (no tier of the menu seals).
seeded
Typebool
What it isThe seed is placed.
feeLocked
Typebool
What it isThe total can never be lowered again.
earlyBuyFeeUntil
Typeuint40
What it isThe first second a buy pays the total alone, a Unix time; zero with no anti-snipe fee. The window began earlyBuyFeeWindow seconds before it, at launch.
graduationTick
Typeint24
What it isThe graduation line's tick (the registered offset until the seed places it).
lpLineTick
Typeint24
What it isThe LP line's tick, likewise.
stage
Typeuint8
What it isThe pool's stage, LaunchHook.Stage: the numbers below.
lpCrossedAt
Typeuint32
What it isWhen the current stretch past the LP line began, while LpCrossed.
lpHeldSeconds
Typeuint16
What it isTime spent past the LP line in earlier stretches, up to the hold.
totalFeeMinPips
Typeuint24
What it isThe floor the total may be lowered to.
totalFeeMaxPips
Typeuint24
What it isThe total registered at launch, for readers.
liquidityPolicy
Typeaddress
What it isA module asked about outside adds; zero for none (no tier names one).
seedTickLower
Typeint24
What it isThe seed's lower tick.
seedTickUpper
Typeint24
What it isThe seed's upper tick.
earlyBuyFeeStartPips
Typeuint24
What it isWhat a buy paid in the launch second, in pips; zero for none.
earlyBuyFeeWindow
Typeuint32
What it isThe seconds the rate takes to fall to the total; zero for none.
seedLiquidity
Typeuint128
What it isThe seed's liquidity.
recipient
Typeaddress
What it isWho the creator side pays: a wallet, a splitter, or the token itself for its holders.

Registration: PoolRegistered's registration: the terms a launch stamps into its pool.

Field

recipient
Typeaddress
What it isWho the creator side pays from launch.
quote
Typeaddress
What it isThe quote asset; zero for native HYPE.
totalFeePips
Typeuint24
What it isThe total at launch, in pips.
totalFeeMinPips
Typeuint24
What it isThe floor.
protocolFeePips
Typeuint24
What it isThe protocol's share.
lpFeePips
Typeuint24
What it isThe LP fee from the LP line on.
feeLocked
Typebool
What it isFixed from birth (the holders or a split).
earlyBuyFeeStartPips
Typeuint24
What it isWhat a buy pays in the launch second, in pips; zero for none.
earlyBuyFeeWindow
Typeuint32
What it isThe seconds it falls over, from the block's time; zero for none.
liquidityPolicy
Typeaddress
What it isThe liquidity policy, or zero.
liquiditySealed
Typebool
What it isOutside liquidity refused.
graduationTicks
Typeuint24
What it isGraduation's offset from the opening, in ticks; zero is graduated from birth.
lpLineTicks
Typeuint24
What it isThe LP line's offset; zero pays the LP fee from birth.

LaunchConfig: ConfigPublished's config and LaunchFactory.getConfig(id): a row a launch picks by its configId.

Field

moduleSetId
Typeuint256
What it isThe module set (hook, token master, splitter master) it launches with.
quote
Typeaddress
What it isThe quote asset; zero for native HYPE.
baseSupply
Typeuint256
What it isThe supply its start tick is set for, in base units (1e9 tokens × 1e18).
tickSpacing
Typeint24
What it isThe pool's tick spacing.
startTick
Typeint24
What it isThe opening tick for the base supply, with the token as currency1; mirrored when the token sorts first.
graduationTicks
Typeuint24
What it isGraduation's offset from the opening, in ticks.
lpLineTicks
Typeuint24
What it isThe LP line's offset.
totalFeePips
Typeuint24
What it isThe total, in pips.
totalFeeMinPips
Typeuint24
What it isThe floor.
protocolFeePips
Typeuint24
What it isThe protocol's share.
lpFeePips
Typeuint24
What it isThe LP fee.
earlyBuyFeeStartPips
Typeuint24
What it isAn anti-snipe fee's start, above the total and at most 99%; zero for none.
earlyBuyFeeWindow
Typeuint32
What it isThe seconds it falls over, at most 30 minutes; zero for none.
liquidityPolicy
Typeaddress
What it isA liquidity policy, or zero.
liquiditySealed
Typebool
What it isOutside liquidity refused.
streamDuration
Typeuint32
What it isSeconds a holders' stream runs.
pushBountyBps
Typeuint16
What it isA pusher's share of each pushed payout, in basis points.
pushFloor
Typeuint128
What it isA pusher's least fee, in the quote's base units.
enabled
Typebool
What it isLaunches may use it. Always false in ConfigPublished: a row is published off and switched on by ConfigEnabled.
exists
Typebool
What it isPublished.

LaunchParams: LaunchFactory.launch's one argument, in this order.

Field

name
Typestring
What it isThe token's name. Not empty.
symbol
Typestring
What it isIts symbol. Not empty.
metadataURI
Typestring
What it isThe metadata JSON's URI, fixed at launch.
profile
TypeProfile
What it isThe image, description and links the token keeps on chain.
configId
Typeuint256
What it isThe row launched under. Ids count from 0: Choose a row.
supply
Typeuint256
What it isWhole tokens × 1e18; 0 for the row's own.
salt
Typebytes32
What it isAny value: the token's address comes from it and the sender.
feeRecipients
Typeaddress[]
What it isWhere the creator's stream goes; empty for the sender's own wallet. The creator's routes.
feeShares
Typeuint16[]
What it isTheir shares of 10,000, in the same order; empty with them.
firstBuyAmount
Typeuint256
What it isThe quote spent on the first buy, its fee included; 0 for none.
firstBuyMinOut
Typeuint256
What it isThe fewest tokens the first buy may return, or the launch reverts FirstBuySlippage.
permit
TypePermit
What it isAn EIP-2612 allowance for an ERC-20 first buy; all zero for none.

Profile: LaunchParams.profile, in this order.

Field

logo
Typestring
What it isThe image's URI.
description
Typestring
What it isThe token's description.
socials
TypeSocials
What it isIts links, below.

Permit: LaunchParams.permit, in this order: one transaction for an ERC-20 first buy.

Field

deadline
Typeuint256
What it isWhen the signature ends. 0: none supplied, and the allowance must already exist.
v
Typeuint8
What it isThe signature's v.
r
Typebytes32
What it isIts r.
s
Typebytes32
What it isIts s.

Socials: LaunchParams.profile.socials, getTokenInfo()'s socials_ and socials(), in this order.

Field

telegram
Typestring
What it isA link, or empty.
twitter
Typestring
What it isA link, or empty.
discord
Typestring
What it isA link, or empty.
website
Typestring
What it isA link, or empty.
extra
Typestring
What it isEmpty for a launch through Montra's site.

RewardView: LaunchLens.rewardView(token, holder).

Field

asset
Typeaddress
What it isWhat holders are paid in: the pool's quote.
directlyRouted
Typebool
What it isThe pool's creator side pays the token itself (a splitter slot naming it is not counted).
eligibleSupply
Typeuint256
What it isThe supply that earns: every balance but the excluded addresses'.
streamingRemaining
Typeuint256
What it isWhat the current stream still has to pay out.
streamingPerSecond
Typeuint256
What it isIts rate, a second.
periodFinish
Typeuint64
What it isWhen it ends, a Unix time.
parked
Typeuint256
What it isArrived too small to restart the stream, waiting for the next.
totalReceived
Typeuint256
What it isEvery unit the token has received for its holders.
totalClaimed
Typeuint256
What it isEvery unit paid out, claimed and pushed.
claimableFromVenue
Typeuint256
What it isWhat distribute() would pull from the hook now, where the creator side pays the token.
earned
Typeuint256
What it isWhat holder could claim now.

For integrators

Terminals, wallets and apps can build on the pools without asking anyone: start with Build on Montra, Contract reference and Public API.

A product that brings launches earns a share of their fees: the Builder programme.

To talk to the team: @MontraXYZ on X.

For AI tools

Every page as Markdown in llms.txt, and all of it in one file at llms-full.txt.