跳到主要内容

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)

常量与限制​

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