Events and data reference
索引器或仪表盘所需的一切:需要监听的事件、如何反向查询一个销售,以及这些文档提到的每一个 结构体、枚举与常量。
目录
索引模型
每种上线方式都以一个 fundManager 地址作为其身份的键,它是每个生命周期事件上的一个 indexed
参数,因此你可以用单个 topic 过滤出某个销售的完整历史。创建事件(PoolCreated、
MicroSaleCreated、BondingCurvePoolCreated)也携带 token,因此你仅凭创建事件就能构建
销售到代币的映射。
indexed 被应用到生命周期事件上的 fundManager 和 user;数字 index 在交易/finalize 事件
上不是 indexed 的,所以请按 fundManager 过滤与关联。
对上线信息流最重要的事件:
PoolCreated/MicroSaleCreated/BondingCurvePoolCreated:一个销售被创建了(对于 microsale 或 Melt Pool,还铸造了一个代币)。Finalized/MicroSaleFinalized/BondingCurveFinalized:代币在 DEX 上上线,交易开始。
Pool 事件
由 presale、fair launch 和 subscription 流程触发。
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);
注意:Finalized 和 Cancelled 属于 pool。microsale 改为触发 MicroSaleFinalized 和
MicroSaleCancelled。在 subscription allocation 事件中,poolIndex 是 indexed 的(不同于
生命周期事件上的数字 index)。
Microsale 事件
所有生命周期事件都以下面这些签名声明。indexed 参数是可过滤的 topic。
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);
注意:microsale 触发 MicroSaleFinalized。通用的 Finalized 事件属于更早的 presale 和
fair-launch pool 流程,而不属于 microsale。
Melt Pool 事件
由 Melt Pool 流程触发。合约把这些拼写为 BondingCurve*——这是 Melt Pool 所运行的定价曲线的
技术名称。参见 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 携带交易后的储备量,因此你无需再发起一次读取就能追踪价格
(reserveQuote / reserveBase)和成交量。BondingCurveSoldOut 会在买光曲线的那笔买入上触发,
这是告诉你池子已准备好毕业的信号。它与 BondingCurveFinalized 是两个独立的时刻,后者在有人
真正调用 finalize 且代币上线时触发,并携带 DEX 的 pair。BondingCurvePoolUpdated 在池子
所有者编辑元数据时触发。
Vault 事件
由 vault 合约触发,而非由 launchpad 触发。请在你从
getMicroSaleByFundManager(fundManager).vault 得到的 vault 地址上过滤它们。
所有基于 VaultBase 构建的 vault 通用:
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
反向查询
你需要的每一个映射都是一个 view 调用。Pool 和 microsale 有相互对应的 getter。
// 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();
对于未知地址,getPoolByFundManager(及其 Melt Pool 对应函数)会返回 pool 0 而不是 revert,
所以在信任结果之前请检查 result.fundManager === fundManager。从一个 MicroSale、Pool 或
BondingCurvePool 中你已经拿到了 token、fundManager 和 owner,因此大多数关联都不需要
第二次调用。Melt Pools 没有按代币查询的 getter,但代币地址是结构体上的一个字段。
数据结构
Pool
由 getPool* 视图返回。哪些字段有意义取决于 pool 类型(fair launch 会把 rate 和 hardCap
留为零;subscription 使用 softCapTokens 而非 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
}
分页的 getContributionInfosByFundManager 返回 ContributionInfoResponse,它是在
ContributionInfo 前面加上 user 地址:
struct ContributionInfoResponse {
address user;
uint256 contribution;
uint256 purchased;
uint256 claimed;
uint256 excessiveRefunded;
}
MicroSale
由每一个 getMicroSale* 视图返回。
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
由 getMicroSaleConfig 和 active-configs 视图返回。
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 始终等于 1,000,000,000 代币的固定总供应量。
ContributionInfo
按用户的账本,由 pool 和 microsale 共享。getContributionInfo(pool)和
getMicroSaleContribution(microsale)会完整返回它;分页的 microsale 响应会去掉
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
由 pool 的 getWhitelistTiers(fundManager) 返回。
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
由 getBondingCurvePool(index) 和 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
}
价格是 reserveQuote / reserveBase。售罄(毕业)意味着 reserveBase == initialBase - totalSellingBase;它是从储备量派生出来的,而非存储为一个状态。
BondingCurveConfig
某个 quote currency 对应的平台曲线模板,由 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
在 CheeseTaxTokenV2 tax-token 上线时于 CreateParamsV2 结构体内部传入。它治理代币的 tax
以及 tax 的去向。tax-token 创建调用在 params 之外还会接受一个尾随的 dexKey(要上线的 DEX)。
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;
}
在这个 creator tax 之上,CheesePad 会额外收取 tax 的 10% 作为平台费(曲线阶段和上线之后); 参见 tokens.md#the-fee-model。
Platform config
getMasterConfig() 返回平台级的设置。
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 是 tax token 的 creator tax 在曲线阶段与上线之后的
平台费;用 getPlatformCutBps() 直接读取它们。参见
tokens.md#the-fee-model。
LaunchDataV1
当你的 vault 工厂审查一次上线时,它的 _reviewV1 所接收的内容。它是上线参数,不含各 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
由 vaultDataSchema()(创建表单)和 vaultUISchema()(操作与可读状态)使用。UI 可以仅凭
这些渲染任意 vault,而不需要 vault 专属的代码。
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;
}
类型说明:Time 是一个绝对的 Unix 时间戳(一个 duration 只是一个以秒为单位的 Uint256)。
MsgValue 是随一次写入以 msg.value 发送的原生 BNB,而不是一个 ABI 参数。decimals 不适用于
Time 或 MsgValue。任何 ApprovalHint 的 spender 始终是该 vault。
枚举
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)
常量与限制
| Constant | Value | Where |
|---|---|---|
| Minted token supply | 1,000,000,000 (18 decimals) | every microsale and Melt Pool token (pools bring their own) |
| Tax cap per side | 10% (1000 BPS) | tax token at launch |
| Template tax cap per side | 5% (500 BPS) | microsale config template |
| Allocation base | 10000 BPS | tax allocation must sum to this |
| Platform fee at finalize | 5% (microsale) / nativeFeePercent (pool) | finalize |
| Melt Pool trade fee | 1% (100 BPS) per trade | every curve buy and sell |
| Emergency withdrawal fee | 10% of the contribution | emergency withdraw |
| Emergency cutoff | last 15 minutes before end | emergency withdraw |
| Pool listing percent | 20 to 100 | pool create |
| Presale soft cap rule | softCap * 4 >= hardCap and softCap < hardCap | presale create |
| Minimum LP lock | 30 days (pool) / 365 days (microsale); 5 minutes on BNB testnet only | finalize with a lock |
| Maximum LP lock | 10 years | microsale create |
| Melt Pool liquidity | LP burned at graduation (permanent) | Melt Pool finalize |
| SplitterVault max payees | 50 | SplitterVault |
| GiftVault bind window | 1 to 365 days | GiftVault launch |