Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ch10-04 predict_manager.move 的用户账户和头寸管理

返回本章

先看市场问题

这里先从市场定义往下看。“predict_manager.move 的用户账户和头寸管理”服务的是 Predict 市场如何被定义、定价、mint、settle 或索引;不要把它读成普通现货订单簿的变体。

源码入口

  • packages/predict/sources/predict_manager.movePredictManager 字段、deposit、withdraw、position 增减。
  • packages/predict/sources/registry.move:创建和分享 manager 的入口与派生 key。
  • packages/deepbook/sources/balance_manager.move:Predict 内部复用的余额模型。

关键定义

PredictManager 把用户余额和预测头寸放在一个共享对象里:

public struct PredictManagerKey(address, u64) has copy, drop, store;

public struct PredictManager has key {
    id: UID,
    owner: address,
    balance_manager: BalanceManager,
    deposit_cap: DepositCap,
    withdraw_cap: WithdrawCap,
    positions: Table<RangeKey, u64>,
}

公开给用户的资金入口:

public fun deposit<T>(self: &mut PredictManager, coin: Coin<T>, ctx: &TxContext)

public fun withdraw<T>(
    self: &mut PredictManager,
    amount: u64,
    ctx: &mut TxContext,
): Coin<T>

包内头寸更新入口:

public(package) fun increase_position(self: &mut PredictManager, key: RangeKey, quantity: u64)
public(package) fun decrease_position(self: &mut PredictManager, key: RangeKey, quantity: u64)

positions 只保存区间数量,不保存成本价、手续费或 PnL。应用要展示收益,必须结合 mint/redeem 事件、交易 digest 或未来 Indexer 读模型。

读市场参数

PredictManager 是每个用户的共享对象,字段包括 owner、DeepBook BalanceManagerDepositCapWithdrawCapTable<RangeKey, u64> positions。registry.move::create_and_share_manager 使用 PredictManagerKey(address, 0) 派生对象 ID,v1 默认每个地址一个 manager。

用户资金先通过 deposit<T>(manager, coin, ctx) 进入内部 BalanceManager,交易时 predict.move 用包内权限调用 manager.withdraw<Quote>(cost, ctx)。头寸只记录 range quantity,不记录成本价;应用层要从事件、交易历史或未来 Indexer 里恢复成本和 PnL。

服务层通常提供 ensurePredictManager(owner):先按 PredictManagerKey(address, 0) 查询对象,不存在再构造创建 PTB。创建之后,后续 deposit、mint、redeem 都使用同一个 manager 对象,避免用户在多个 manager 间分散余额和头寸。

因为 positions table 只保存 quantity,成本价、fee、mint 时间和 realized PnL 需要从交易事件或未来 Indexer 读模型恢复。当前迁移状态下,应用可以本地记录提交摘要和 digest,但不能把未完成的 Predict Indexer 当成唯一账本。

Predict 边界判断

  • manager 创建、deposit、mint 应拆成可组合 PTB,允许前端一次签名完成初始化。
  • 任何交易都校验 ctx.sender() 与 manager owner 一致,避免代签或错误对象。
  • PnL 展示明确区分链上 position quantity 和链下成本记录。

动手检查

  • 为什么 manager ID 派生要包含 owner,而 market key 不包含 owner?
  • 如果用户换钱包或误选别人的 manager,Move 层会在哪里拒绝?
  • 没有稳定 Indexer 时,应用如何保存和恢复用户成本信息?