跳转到内容

结算、迁移与领取

当前 ABI:版本化源码 c96cd0d。示例使用已激活的 PACKAGE_VERSION 对象;历史非版本化地址需要不同 ABI。详见版本管理及部署参考。

认购窗口关闭后,或设有硬顶的预售满足提前结束条件后,以下操作均无需特定权限。任何应用或机器人均可提交交易。时间到达或募资达标不会自动执行结算或迁移;仍需成功的链上交易。

任何人均可在预售处于 Open 且满足以下任一条件时调用 settle(presale, package_version, clock):

  • now ≥ end_ms;或
  • 预售可提前结束:硬顶设置了 closes_when_filled,已生效(now ≥ start_ms + starts_after_ms),且 total_commitments ≥ raise_target。

否则以 EPresaleNotEnded 中止。结算结果:

  • 认购总额达到或超过目标:变为 Funded,发出 PresaleFunded。
  • 低于目标:变为 Cancelled,发出 PresaleCancelled。

提前结束时,窗口在结算时关闭。存储的 duration_ms 改为实际运行时长,因此 end_ms 和流动性部署截止时间(end_ms + liquidity_window_ms)均根据实际结束时间计算。PresaleFunded 用 end_ms 和 liquidity_deadline_ms 携带这两个时间,早于 PresaleOpened 最初公布的时间。

  • 未设硬顶的预售即使第一天达标也不会提前结束,后续钱包仍可按统一成交比例参与。
  • 在硬顶生效前已超额认购的预售,可从硬顶生效时开始结束。
  • 设置 closes_when_filled = false 时,预售持续到原定结束时间,以便按宣布的时间开放池。

结算和迁移可在同一笔交易完成。由于迁移无需特定权限,补足募资的钱包可在一笔交易中认购、结算、迁移并率先在新池买入。池初始价格与按时结束的情况相同,改变的是谁能确保率先买入。希望公开指定开池时间的团队应设 closes_when_filled = false。

在被取消之前,任何人均可迁移 Funded 预售。迁移支付 Blast 费用(指定合作伙伴时暂存费用),支付或设置各募资及代币接收方的分期解锁,按 new 在 VenueConfig 中记录的档位建池,注入全价格区间仓位,并共享持有仓位或手续费领取凭证的 Vault。交易平台调用失败时,整笔交易回滚。

// Settle and migrate a funded Bluefin sale in one transaction.
const tx = new Transaction();
tx.moveCall({
target: `${PKG}::blast_presale::settle`,
typeArguments: [MEME, SUI],
arguments: [tx.object(PRESALE), tx.object(PACKAGE_VERSION), tx.object.clock()],
});
const [fee] = tx.splitCoins(tx.gas, [creationFee]); // Bluefin's current pool-creation fee
tx.moveCall({
target: `${PKG}::bluefin::migrate`,
typeArguments: [MEME, SUI],
arguments: [
tx.object(PRESALE),
tx.object(PACKAGE_VERSION),
tx.object(FEE_POLICY),
tx.object(VENUE_CONFIG),
tx.object(MEME_CURRENCY),
tx.object(SUI_CURRENCY),
tx.object(BLUEFIN_CONFIG),
fee,
tx.object.clock(),
],
});

creationFee 必须等于提交时 Bluefin config::get_pool_creation_fee_amount<SUI> 返回的值,其他金额会被拒绝。VENUE_CONFIG 是共享 VenueConfig,用于读取 bluefin::new 记录的档位。MEME_CURRENCY 和 SUI_CURRENCY 是两币种在代币注册表中的共享 Currency 对象。创建的池为 Pool<Meme, Quote>,预售代币始终是 coin A。

cetus::migrate<Meme, Quote, CoinA, CoinB>(sale, package_version, fee_policy, venue_config, cetus_config, pools, burn_manager, clock)

  • CoinA 与 CoinB 是按 Cetus 规范排序的两种代币,即 factory::is_right_order 接受的顺序。可用 dev-inspect 检查任一顺序。顺序错误以 EInvalidCoinOrder 中止。
  • 共享对象包括:预售、FeePolicy、VenueConfig(读取预留的 PoolCreationCap 及 cetus::new 记录的 tick 间距)、Cetus GlobalConfig、Pools 和 LP 销毁 BurnManager。
  • 仓位经 Cetus LP 销毁机制销毁,金库仅保留收取手续费的凭证。

迁移后调用 pay_protocol_fees_with_partner(presale, package_version, fee_policy, partner, clock)。任何人均可调用,仅执行一次:支付合作伙伴在 Blast 募资费用中的分成,将剩余募资费用及 Blast 代币费用支付给 Blast。

预售处于 Migrated 或 Cancelled 时,任何人均可调用 claim(presale, package_version, participant, clock),款项始终支付给 participant。

  • Migrated:领取参与者的代币和超额认购退款。
  • Cancelled:退还全部认购金额。
  • 每个钱包仅领取一次,领取会移除其认购记录。
  • 若启用了参与者分期解锁,代币进入新建的共享 Vesting<Meme>,从领取时开始计算;退款立即支付。

可在一笔交易中批量领取:

const claims = new Transaction();
for (const participant of participants) {
claims.moveCall({
target: `${PKG}::blast_presale::claim`,
typeArguments: [MEME, SUI],
arguments: [claims.object(PRESALE), claims.object(PACKAGE_VERSION), claims.pure.address(participant), claims.object.clock()],
});
}

Claimed 报告 tokens、quote_refund、remaining_participants 和 vesting_id。

接收方的解锁从迁移时开始,参与者的代币解锁从其领取时开始。每份安排均为不可变 blast_fun_vesting 包的共享 Vesting<T>,受益人固定,无人有权取消。

  • blast_fun_linear_vesting::claim<T>(vesting, clock):任何人可调用,将新解锁的全部金额发送给受益人。无新增可提取金额时,以 ENothingClaimable 中止。
  • 时刻 t 的已解锁金额:start + cliff_ms 前为零;从 start + period_ms × periods 起全部解锁;其余情况为 floor(total × floor((t − start) ÷ period_ms) ÷ periods)。
  • blast_fun_linear_vesting::close_irrevocable<T>(vesting):任何人可调用,删除余额已提完的解锁对象。

取消逾期未迁移的预售

跳转到“取消逾期未迁移的预售”

预售处于 Funded 且 now ≥ end_ms + liquidity_window_ms 时,任何人均可调用 cancel_unlaunched(presale, package_version, clock)。提前结束时,end_ms 为实际结束时间。预售变为 Cancelled,所有参与者均可领取全额退款。若始终无人结算,也可在截止时间后于同一笔交易中结算并取消。

当前代码没有从已取消预售中收回已铸造代币的路径。创建者可用 destroy_cap(presale, presale_cap) 销毁 PresaleCap。