Skip to main content

Events and data reference

Everything an indexer or dashboard needs: the events to listen for, how to reverse-look-up a sale, and every struct, enum, and constant these docs mention.

Contents​

Indexing model​

Every launch style keys its identity on a fundManager address, an indexed parameter on every lifecycle event, so you can filter the whole history of one sale with a single topic. The create events (PoolCreated, MicroSaleCreated, BondingCurvePoolCreated) also carry the token, so you can build the sale-to-token map from the create event alone.

indexed is applied to fundManager and user on the lifecycle events; the numeric index is not indexed on the trade/finalize events, so filter and join on fundManager.

Events that matter most for a listings feed:

  • PoolCreated / MicroSaleCreated / BondingCurvePoolCreated: a sale was created (and for a microsale or Melt Pool, a token was minted).
  • Finalized / MicroSaleFinalized / BondingCurveFinalized: the token was listed on the DEX and trading started.

Pool events​

Emitted by the presale, fair launch, and subscription flows.

event PoolCreated(uint256 index, address indexed fundManager, address owner, address token, uint256 timestamp);

event Contributed(uint256 index, address indexed fundManager, address indexed user, uint256 amount, uint256 timestamp);

event Claimed(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 claimed,
uint256 totalPurchased,
uint256 timestamp
);

event ExcessiveRefunded(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 amount,
uint256 total,
uint256 timestamp
);

event WithdrawContribution(uint256 index, address indexed fundManager, address indexed user, uint256 amount, uint256 timestamp);

event EmergencyWithdrawContribution(uint256 index, address indexed fundManager, address indexed user, uint256 amount, uint256 timestamp);

event Finalized(uint256 index, address indexed fundManager, uint256 timestamp);
event Cancelled(uint256 index, address indexed fundManager, uint256 timestamp);
event PoolUpdated(uint256 index, address indexed fundManager, uint256 timestamp);

// whitelist
event WhitelistRootUpdated(address indexed fundManager, bytes32 root, uint256 timestamp);
event WhitelistTierAdded(address indexed fundManager, uint256 tier, uint256 startTime, uint256 duration, uint256 timestamp);
event WhitelistTierUpdated(address indexed fundManager, uint256 tier, uint256 startTime, uint256 duration, uint256 timestamp);

// subscription allocation
event AllocationSubmitted(uint256 indexed poolIndex, address indexed fundManager, bytes32 allocationRoot, uint256 totalVolumePurchased);
event AllocationApproved(uint256 indexed poolIndex, address indexed fundManager);
event AllocationRevoked(uint256 indexed index, address indexed fundManager);

Note: Finalized and Cancelled belong to pools. Microsales emit MicroSaleFinalized and MicroSaleCancelled instead. On the subscription allocation events, poolIndex is indexed (unlike the numeric index on the lifecycle events).

Microsale events​

All lifecycle events are declared with these signatures. indexed parameters are filterable topics.

event MicroSaleCreated(
uint256 indexed index,
address indexed fundManager,
address indexed owner,
address token,
uint256 configId,
uint256 timestamp
);

event MicroSaleContributed(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 amount,
uint256 timestamp
);

event MicroSaleFinalized(uint256 index, address indexed fundManager, uint256 timestamp);

event MicroSaleClaimed(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 claimed,
uint256 timestamp
);

event MicroSaleWithdraw(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 amount,
uint256 timestamp
);

event MicroSaleEmergencyWithdraw(
uint256 index,
address indexed fundManager,
address indexed user,
uint256 amount,
uint256 timestamp
);

event MicroSaleCancelled(uint256 index, address indexed fundManager, uint256 timestamp);

event MicroSaleUpdated(uint256 indexed index, address indexed fundManager, uint256 timestamp);

Note: microsales emit MicroSaleFinalized. The generic Finalized event belongs to the older presale and fair-launch pool flow, not to microsales.

Melt Pool events​

Emitted by the Melt Pool flow. The contract spells these BondingCurve* — that is the technical name for the pricing curve a Melt Pool runs on. See melt-pool.md.

event BondingCurvePoolCreated(
uint256 indexed index,
address indexed fundManager,
address owner,
address token,
address quoteToken,
uint256 timestamp
);

// one per buy and per sell
event BondingCurveTraded(
uint256 index,
address indexed fundManager,
address indexed user,
bool isBuy,
uint256 quoteAmount, // BNB in (buy) or out (sell)
uint256 baseAmount, // tokens out (buy) or in (sell)
uint256 reserveBase, // reserves after the trade
uint256 reserveQuote,
uint256 timestamp
);

// the buy that takes the last curve token
event BondingCurveSoldOut(uint256 index, address indexed fundManager, uint256 timestamp);

event BondingCurveFinalized(uint256 index, address indexed fundManager, address pair, uint256 timestamp);

event BondingCurvePoolUpdated(uint256 indexed index, address indexed fundManager, uint256 timestamp);

BondingCurveTraded carries the post-trade reserves, so you can track price (reserveQuote / reserveBase) and volume without a follow-up read. BondingCurveSoldOut fires on the buy that exhausts the curve, which is your cue that the pool is ready to graduate. That is a separate moment from BondingCurveFinalized, which fires when someone actually calls finalize and the token lists, and carries the DEX pair. BondingCurvePoolUpdated fires when the pool owner edits the metadata.

Vault events​

Emitted by the vault contracts, not by the launchpad. Filter them on the vault address you get from getMicroSaleByFundManager(fundManager).vault.

Common to every vault built on VaultBase:

event Bound(address indexed token);      // fee-receiver wired to its token, once
event RevenueReceived(uint256 amount); // best-effort signal when the token settles tax

SplitterVault:

event Distributed(uint256 amount);
event Paid(address indexed payee, uint256 amount);
event PayFailed(address indexed payee, uint256 amount); // payee could not receive; kept as owed
event Claimed(address indexed payee, uint256 amount);

GiftVault:

event BeneficiaryBound(address indexed beneficiary, uint256 nonce, bool viaRelayer);
event Distributed(uint256 amount);
event Paid(address indexed to, uint256 amount);
event PayFailed(address indexed to, uint256 amount);
event Claimed(address indexed to, uint256 amount);
event Locked();
event DividendDistributed(uint256 amount); // timeout fallback fired; vault is now dividend-only

Reverse lookups​

Every mapping you need is a view call. Pools and microsales have parallel getters.

// microsales
await launchpad.getMicroSaleByFundManager(fundManager);
await launchpad.getMicroSaleByToken(token); // 1:1
await launchpad.getMicroSaleByVault(vault); // vault launches
await launchpad.getMicroSale(index);
await launchpad.getMicroSalesCount();

// pools
await launchpad.getPoolByFundManager(fundManager); // confirm result.fundManager === fundManager
await launchpad.getPoolByIndex(index);
await launchpad.getPoolCount();

// melt pools
await launchpad.getBondingCurvePoolByFundManager(fundManager); // confirm result.fundManager === fundManager
await launchpad.getBondingCurvePool(index);
await launchpad.getBondingCurvePoolsCount();

A getPoolByFundManager (and its Melt Pool counterpart) for an unknown address returns pool 0 rather than reverting, so check result.fundManager === fundManager before trusting it. From a MicroSale, Pool, or BondingCurvePool you already have token, fundManager, and owner, so most joins do not need a second call. Melt Pools have no by-token getter, but the token address is a field on the struct.

Data structures​

Pool​

Returned by the getPool* views. Which fields are meaningful depends on the pool type (a fair launch leaves rate and hardCap at zero; a subscription uses softCapTokens instead of softCap).

struct Pool {
uint256 index;
PoolTypeIndex poolType;
address owner;
address token;
address currency; // address(0) = native (BNB)
address fundManager; // the sale handle
address router; // address(0) for a manual-listing pool
uint256 startTime;
uint256 endTime;
uint256 publicSaleStartTime; // whitelist window ends here
uint256 whitelistTierCount;
uint256 minContribution;
uint256 maxContribution;
uint256 softCap; // currency; presale + fair launch
uint256 hardCap; // currency; presale
uint256 softCapTokens; // tokens; subscription
uint256 totalSellingTokens; // fair launch + subscription
uint256 hardCapTokensPerUser; // subscription
uint256 rate; // tokens per currency unit; presale + subscription
uint256 listingRate;
uint256 lockDuration; // LP lock seconds; 0 = burn
uint256 listingPercent; // percent of the raise into liquidity
uint256 buybackPercent;
uint256 affiliateBps;
RefundType refundType; // Refund | Burn (unsold tokens)
State state; // Active | Finalized | Cancelled
uint256 listedAt;
uint256 claimTime;
uint256 totalRaised;
uint256 totalCommitted; // subscription commitments before allocation
uint256 totalVolumePurchased; // tokens sold / allocated
int256 lockId; // locker id when locked, else -1
string poolDetails;
string kycDetails;
bytes32 whitelistRoot; // 0 = no whitelist
bytes32 allocationRoot; // subscription / overflow allocation
bytes32 noAllocationRoot; // overflow non-allocated refunds
uint256 tgePercent; // vesting: released at claim start
uint256 cyclePercent; // vesting: released per cycle
uint256 cycle; // vesting: cycle length in seconds
bool requireContributorValidation; // contributions need a platform signature
}

The paginated getContributionInfosByFundManager returns ContributionInfoResponse, which is ContributionInfo with the user address prepended:

struct ContributionInfoResponse {
address user;
uint256 contribution;
uint256 purchased;
uint256 claimed;
uint256 excessiveRefunded;
}

MicroSale​

Returned by every getMicroSale* view.

struct MicroSale {
uint256 index; // creation index
MicroSaleTypeIndex microSaleType;
address owner; // creator
address token; // minted token
address currency; // raise currency; address(0) = native (BNB)
address fundManager; // the sale handle
address router; // DEX router used at finalize
uint256 startTime;
uint256 endTime;
uint256 hardCap; // in the raise currency
uint256 totalSellingTokens; // presale allocation
uint256 rate; // presale rate; purchased = amount * rate / 1e18
uint256 listingRate; // opening DEX price basis
State state; // Active | Finalized | Cancelled
uint256 filledAt; // when the hard cap filled (0 if not)
uint256 listedAt; // when finalized (0 if not)
uint256 totalRaised;
uint256 totalVolumePurchased; // total tokens sold
uint256 configId; // template it launched from
string poolDetails; // free-form metadata
string kycDetails; // platform-set KYC metadata
uint256 maxContribution; // per-wallet cap; 0 = unlimited
uint256 lockDuration; // LP lock seconds; 0 = LP burned
int256 lockId; // locker id when locked, else -1
address vault; // attached vault, or address(0)
address vaultFactory; // factory that made the vault, or address(0)
}

MicroSaleConfig​

Returned by getMicroSaleConfig and the active-configs views.

struct MicroSaleConfig {
uint256 configId;
uint256 presaleTokens; // tokens sold in the presale
uint256 lpTokens; // tokens paired into liquidity
uint256 hardCap; // in the template's raise currency
uint256 duration; // sale length in seconds
uint256 buyTaxBps; // template buy tax (used by templated tax tokens)
uint256 sellTaxBps; // template sell tax
uint256 taxDuration; // template tax lifetime
bool active;
}

presaleTokens + lpTokens always equals the fixed total supply of 1,000,000,000 tokens.

ContributionInfo​

The per-user ledger, shared by pools and microsales. getContributionInfo (pools) and getMicroSaleContribution (microsales) return it in full; the paginated microsale response drops excessiveRefunded.

struct ContributionInfo {
uint256 contribution; // amount put in, in the raise currency
uint256 purchased; // tokens allocated
uint256 claimed; // tokens claimed so far
uint256 excessiveRefunded; // subscription / overflow refund; unused by microsales
}

// paginated microsale response shape
struct MicroSaleContributionInfoResponse {
address user;
uint256 contribution;
uint256 purchased;
uint256 claimed;
}

WhitelistTier​

Returned by getWhitelistTiers(fundManager) for a pool.

struct WhitelistTier {
uint256 tier; // 1-indexed
uint256 startTime; // when the tier opens
uint256 duration; // seconds the tier stays open; 0 = single open-ended tier
string description;
}

BondingCurvePool​

Returned by getBondingCurvePool(index) and getBondingCurvePoolByFundManager(fundManager).

struct BondingCurvePool {
uint256 index;
address owner;
address token;
address quoteToken; // address(0) = native (BNB); otherwise an allowed ERC20 quote token
address fundManager; // the pool handle
address router;
uint256 initialBase; // virtual base reserve seed
uint256 initialQuote; // virtual quote reserve seed
uint256 totalSellingBase; // tokens sellable before graduation
uint256 reserveBase; // current base reserve
uint256 reserveQuote; // current quote reserve
CurveState state; // Active | Finalized
uint256 listedAt; // graduation timestamp, 0 until finalized
uint8 tokenType; // 0 = no-tax (CheeseToken), 4 = tax (CheeseTaxTokenV2)
address vault; // attached vault, or address(0)
address vaultFactory; // factory that made the vault, or address(0)
string poolDetails; // free-form metadata
}

Price is reserveQuote / reserveBase. Sold out (graduated) means reserveBase == initialBase - totalSellingBase; it is derived from reserves, not stored as a state.

BondingCurveConfig​

The platform curve template for a quote currency, returned by getBondingCurveConfig(quoteToken).

struct BondingCurveConfig {
bool active; // curves cannot be created against an inactive config
uint256 initialBase; // virtual base reserve seed
uint256 initialQuote; // virtual quote reserve seed
uint256 totalSellingBase; // tokens sellable before graduation
}

TaxConfig​

Passed inside the CreateParamsV2 struct for the CheeseTaxTokenV2 tax-token launches. Governs the token's tax and where the tax goes. The tax-token create calls also take a trailing dexKey (the DEX to list on) alongside the params.

struct TaxAllocation {   // BPS; the four must sum to 10000
uint16 feeReceiver; // to the fee receiver (wallet or vault)
uint16 holders; // to holders as dividends
uint16 burn; // to the dead address
uint16 liquidity; // added back as LP
}

struct TaxConfig {
uint256 buyTaxBps; // <= 1000 (10%)
uint256 sellTaxBps; // <= 1000 (10%); buyTaxBps + sellTaxBps must be > 0
uint256 taxDuration; // seconds after listing that tax applies; must be > 0
uint256 antiFarmerDuration; // seconds of the anti-farmer window; <= taxDuration
TaxAllocation allocation; // must sum to 10000
address feeReceiver; // wallet path only; vault path binds the vault instead
address quoteToken; // 0 fills from the template binding (WETH or an allowed ERC20 quote token)
uint256 minHolderShare; // required > 0 only if allocation.holders > 0
// Anti-farmer venue prediction — filled by the launchpad from the chosen DEX, not
// by the caller. Leave at zero defaults.
address v3Factory;
bytes32 v2PairInitCodeHash;
bytes32 v3PoolInitCodeHash;
uint24[] v3FeeTiers;
}

On top of this creator tax, CheesePad takes an additional 10% platform fee on the tax (curve phase and after listing); see tokens.md#the-fee-model.

Platform config​

getMasterConfig() returns the platform-wide settings.

struct LaunchpadMasterConfig {
address feeTo; // platform fee + creation fee sink
address locker; // LP locker for locked-liquidity sales
address affiliateProgram;
address buybackManager;
address verificationWallet;
uint256 creationFee; // pool creation fee (not microsale)
uint128 nativeFeePercent;
uint256 maxAffiliateBps;
uint256 fairLaunchMaxDuration;
uint256 totalParticipants;
address cheeseTokenHelper; // shared swap/liquidity helper for tax tokens
address platformRole; // vault emergency-rescue backstop
address giftRelayerSigner; // EIP-712 attestor for GiftVault identity binds
uint256 microSaleCreationFee; // flat native fee to create a microsale
address swapRouter; // shared upgradeable router for CheeseTaxTokenV2 processors
uint16 platformCutPreBps; // platform fee on curve-phase creator tax (BPS)
uint16 platformCutPostBps; // platform fee on post-listing creator tax (BPS)
}

platformCutPreBps / platformCutPostBps are the platform fee on a tax token's creator tax during the curve phase and after listing; read them directly with getPlatformCutBps(). See tokens.md#the-fee-model.

LaunchDataV1​

What your vault factory's _reviewV1 receives when it vets a launch. It is the launch parameters, without the per-vault vaultData.

struct LaunchDataV1 {
uint256 configId;
address quoteToken;
uint256 buyTaxBps;
uint256 sellTaxBps;
uint256 taxDuration;
uint16 feeReceiverBps;
uint16 holdersBps;
uint16 burnBps;
uint16 liquidityBps;
uint256 minDispatch;
uint256 minHolderShare;
address creator;
}

Vault schema types​

Used by vaultDataSchema() (creation form) and vaultUISchema() (actions and readable state). A UI renders any vault from these without vault-specific code.

enum FieldType {
String, Address, Uint16, Uint256, Uint128, Bool, Bytes, Bytes32, Time, MsgValue
}

struct Field {
string name;
FieldType fieldType;
bool isArray;
uint8 decimals; // UI multiplies inputs / divides outputs by 10^decimals
string hint;
}

struct VaultDataSchema { // how to encode vaultData for createVault
string description;
bool isArray; // true => vaultData is a tuple[]; false => a single tuple
Field[] fields;
}

struct ApprovalHint { // an ERC20 approval a UI must prompt before a write
string tokenRef; // "token", "quoteToken", or a 0x address literal
string amountField; // input field holding the amount; "*" = max approval
}

struct Method {
string name;
bytes4 selector;
bool isWrite; // true = tx button; false = read field
Field[] inputs;
Field[] outputs;
ApprovalHint[] approvals;
string hint;
}

struct VaultUISchema {
string vaultType;
string description;
Method[] methods;
}

Type notes: Time is an absolute Unix timestamp (a duration is just a Uint256 of seconds). MsgValue is native BNB sent as msg.value with a write, not an ABI argument. decimals does not apply to Time or MsgValue. The spender for any ApprovalHint is always the vault.

Enums​

enum State { Active, Finalized, Cancelled }   // 0, 1, 2; used by pools and microsales

enum PoolTypeIndex { // Pool.poolType
Presale, // 0
FairLaunch, // 1
Subscription, // 2
OverflowPresale, // 3, not currently creatable
OverflowFairLaunch // 4, not currently creatable
}

enum RefundType { Refund, Burn } // 0, 1; handling of unsold pool tokens

enum SubscriptionCalculationStage { // getSubscriptionCalculationStage
notCalculated, // 0
needConfirm, // 1
calculated // 2, claiming can open
}

enum MicroSaleTypeIndex { Presale } // only one type today

enum CurveState { Active, Finalized } // 0, 1; BondingCurvePool.state (sold-out is derived)

Constants and limits​

ConstantValueWhere
Minted token supply1,000,000,000 (18 decimals)every microsale and Melt Pool token (pools bring their own)
Tax cap per side10% (1000 BPS)tax token at launch
Template tax cap per side5% (500 BPS)microsale config template
Allocation base10000 BPStax allocation must sum to this
Platform fee at finalize5% (microsale) / nativeFeePercent (pool)finalize
Melt Pool trade fee1% (100 BPS) per tradeevery curve buy and sell
Emergency withdrawal fee10% of the contributionemergency withdraw
Emergency cutofflast 15 minutes before endemergency withdraw
Pool listing percent20 to 100pool create
Presale soft cap rulesoftCap * 4 >= hardCap and softCap < hardCappresale create
Minimum LP lock30 days (pool) / 365 days (microsale); 5 minutes on BNB testnet onlyfinalize with a lock
Maximum LP lock10 yearsmicrosale create
Melt Pool liquidityLP burned at graduation (permanent)Melt Pool finalize
SplitterVault max payees50SplitterVault
GiftVault bind window1 to 365 daysGiftVault launch