Skip to main content

Minted tokens

Microsales and Melt Pools each mint a fresh ERC20 at creation. Standard pools—presales, fair launches, and subscriptions—list a token supplied by the creator and are not covered here.

Token contracts​

CheeseTokenCheeseTaxTokenV2
TOKEN_TYPE()04
Buy/sell taxnoneindependent rates, each at most 10%
Minted bycreateMicroSaleNoTaxToken, createBondingCurveNoTaxToken*createMicroSaleTaxTokenV2, createMicroSaleTaxTokenWithVaultV2, createBondingCurveTaxTokenV2*, createBondingCurveTaxTokenWithVaultV2
Revenue routing—fee receiver, holder dividends, burn, and liquidity

TOKEN_TYPE() == 3 identifies a CheeseTaxToken. Use its dedicated ABI when reading a type-3 token; the create paths in the table above mint types 0 and 4.

Both tokens have:

  • A fixed supply of 1,000,000,000 tokens with 18 decimals.
  • Standard ERC20 reads, approvals, transfers, and Transfer / Approval events.
  • owner() == address(0) after launch. Ownership is renounced during initialization.
  • A fundManager bound to the microsale or Melt Pool that minted the token.
  • Pre-listing venue protection. Wallet-to-wallet transfers are allowed, while configured trading venues cannot be seeded before the official listing.

configurator is the launchpad address that initializes the token. For CheeseToken, it binds the fund manager once. For CheeseTaxTokenV2, it also binds the fee receiver and revenue contracts and can register additional taxed pools. It is not a token-owner wallet.

ABIs​

import { ethers } from "ethers";
import CheeseTokenABI from "./abi/CheeseToken.json";
import CheeseTaxTokenABI from "./abi/CheeseTaxToken.json";
import CheeseTaxTokenV2ABI from "./abi/CheeseTaxTokenV2.json";

const tokenType = await new ethers.Contract(
TOKEN_ADDRESS,
["function TOKEN_TYPE() view returns (uint8)"],
provider,
).TOKEN_TYPE();

const abi =
tokenType === 0n
? CheeseTokenABI
: tokenType === 3n
? CheeseTaxTokenABI
: tokenType === 4n
? CheeseTaxTokenV2ABI
: undefined;
if (!abi) throw new Error(`Unsupported CheesePad token type: ${tokenType}`);

const token = new ethers.Contract(TOKEN_ADDRESS, abi, provider);

Download: CheeseToken.json · CheeseTaxToken.json · CheeseTaxTokenV2.json.

The Launchpad ABI is available at Launchpad.json. Current token source is published in cheesepad-ai/cheesepad-contracts.

Common token reads​

const [name, symbol, decimals, totalSupply, tokenType, listed, manager] = await Promise.all([
token.name(),
token.symbol(),
token.decimals(),
token.totalSupply(),
token.TOKEN_TYPE(),
token.tradingStarted(),
token.fundManager(),
]);
GetterTypeMeaning
name / symbolstringvalues chosen at launch
decimalsuint8always 18
totalSupply / TOTAL_SUPPLYuint256always 1_000_000_000e18
TOKEN_TYPEuint80 for CheeseToken, 3 for CheeseTaxToken, 4 for CheeseTaxTokenV2
owneraddresszero address after initialization
configuratoraddresslaunchpad that initialized and wired the token
fundManageraddressmicrosale or Melt Pool handle
tradingStartedboolwhether the official DEX listing has started
pair (CheeseToken) / PAIR (CheeseTaxTokenV2)addressmain token/quote pair

Use TOKEN_TYPE() as the ABI discriminator. It is useful metadata, but it is not proof that a token was minted by CheesePad; use the launchpad events described below for provenance.

CheeseToken​

CheeseToken is the no-tax token. Its token-specific reads are intentionally small:

GetterMeaning
DECIMALSfixed decimal count, 18
paircanonical token/quote pair
tradingStartedfalse until the official first liquidity seed
isPreListingBlockedVenue(address)whether an address is blocked as a pre-listing venue

Before listing, normal wallet and launchpad custody transfers work, but transfers involving a blocked trading venue revert. The official liquidity seed sets tradingStarted to true; ordinary ERC20 behavior then applies everywhere.

CheeseTaxTokenV2​

CheeseTaxTokenV2 has a four-stage lifecycle:

StateValueMeaning
BondingCurve0pre-listing; no token-level DEX tax
TaxEnforcedAntiFarmer1taxes buys and sells through every registered pool
TaxEnforced2taxes buys and sells through mainPool
TaxFree3tax window has ended

The token starts at state 0 for both microsales and Melt Pools. The official DEX listing sets tradingStarted, tradingStartedAt, and both expiration timestamps. For a Melt Pool, the launchpad itself withholds creator tax from curve trades in the quote currency (see the fee model); the token remains in state 0 until graduation.

Tax and lifecycle reads​

const [
buyBps,
sellBps,
duration,
antiFarmerDuration,
poolState,
allocation,
feeReceiver,
quoteToken,
] = await Promise.all([
token.BUY_TAX_BPS(),
token.SELL_TAX_BPS(),
token.TAX_DURATION(),
token.antiFarmerDuration(),
token.poolState(),
token.allocation(),
token.FEE_RECEIVER(),
token.QUOTE_TOKEN(),
]);

const now = BigInt(Math.floor(Date.now() / 1000));
const taxWindowOpen =
(await token.tradingStarted()) && now < poolState.taxExpirationTime;
const allRegisteredPoolsTaxed =
taxWindowOpen && now < poolState.antiFarmerExpirationTime;
GetterMeaning
BUY_TAX_BPS / SELL_TAX_BPScurrent per-side rates in BPS; each starts at no more than 1000
TAX_BPScurrent maximum of the buy and sell rates
TAX_DURATIONconfigured tax window in seconds after listing
antiFarmerDurationinitial multi-pool tax window in seconds
state()current stored lifecycle state, 0–3
poolState()state, current rates, liquidation threshold, and expiration timestamps
allocation()feeReceiver, holders, burn, and liquidity BPS; sum is 10000
FEE_RECEIVERwallet or vault receiving its allocation slice
QUOTE_TOKENasset used to settle tax revenue
PAIR / mainPoolmain listing pool
isPool(address)whether an address is a registered taxed pool
isPreListingGuardedVenue(address)whether a venue is blocked before listing
taxProcessorcontract that swaps and routes collected tax
dividendTrackerholder-dividend ledger; zero when the holder allocation is zero
liquidationThresholdcurrent token amount that can trigger batched tax processing

state() updates on transfers, so an idle token may retain its previous stored state after an expiration timestamp. Use the timestamps in poolState() when displaying whether a window is open. The next transfer advances the stored state and sets the current tax rates to zero when the tax window has ended.

Revenue allocation​

Collected tax is processed in batches and split by allocation():

  • feeReceiver is settled to the configured wallet or vault.
  • holders is distributed through dividendTracker in the quote token.
  • burn is sent to the dead address.
  • liquidity is paired and added as LP.

When a token has no eligible holder shares, processing reallocates the holder slice across the other configured destinations. The token adjusts its liquidation threshold between MIN_LIQ_THRESHOLD() and START_LIQ_THRESHOLD() based on processing results.

The fee model​

A CheeseTaxTokenV2 has two fee layers worth keeping separate: the creator tax the launcher configures, and the platform fee CheesePad charges on top.

Creator tax. You set BUY_TAX_BPS / SELL_TAX_BPS and an allocation() across feeReceiver / holders / burn / liquidity. That is your revenue and your tokenomics — you choose the rates and the split.

Platform fee. On top of the creator tax, CheesePad charges:

PhaseTrade feePlatform fee on the creator tax
Curve phase (Melt Pool, before graduation)1% of every buy and sellan additional 10% platform fee on the creator tax
After graduation / listingnonean additional 10% platform fee on the creator tax

While a Melt Pool is on the curve, every trade pays the flat 1% trade fee, and CheesePad takes an additional 10% platform fee on the creator tax the curve collects. Once the token graduates and lists (or, for a microsale, from the moment it lists), the 1% trade fee no longer applies, but the 10% platform fee on the creator tax continues for as long as the tax is live. A no-tax CheeseToken has no creator tax, so it pays only the 1% fee while on the curve and nothing after listing.

The platform-fee rate is read from the launchpad's on-chain config (getPlatformCutBps() returns the curve-phase and post-listing rates in BPS), so treat the 10% figures as the current schedule rather than a hardcoded constant.

Detecting a CheesePad token​

A token is platform-minted when it appears in a MicroSaleCreated or BondingCurvePoolCreated event emitted by the CheesePad launchpad address. PoolCreated describes a standard pool whose token was supplied by the creator, so exclude it when building a list of minted tokens.

import LaunchpadABI from "./abi/Launchpad.json";
const launchpad = new ethers.Contract(LAUNCHPAD, LaunchpadABI, provider);

const [microsales, meltPools] = await Promise.all([
launchpad.queryFilter(launchpad.filters.MicroSaleCreated(), fromBlock, toBlock),
launchpad.queryFilter(launchpad.filters.BondingCurvePoolCreated(), fromBlock, toBlock),
]);

for (const event of [...microsales, ...meltPools]) {
const { token, fundManager } = event.args;
const launchStyle =
event.eventName === "MicroSaleCreated" ? "microsale" : "melt-pool";
// Persist token, fundManager, launchStyle, block number, and transaction hash.
}

For point lookups, the launchpad also exposes getMicroSaleByToken(token) and getBondingCurvePoolByToken(token). Both return the complete launch record and reject an unknown token.