算法
HyperPredictV1Pair 的角色
HyperPredictV1Pair 是一个链上交易对,与单个基础资产和交易间隔(intervalSeconds)绑定。每个交易对负责:
- 让操作员(一个自动化机器人)从 Pyth 预言机中拉取价格并按顺序推进回合(
epoch) - 接受投注者的赌注和头寸(牛市/熊市)并将其存储在
ledger和userRounds映射中 - 每当一个回合成功结束时,计算奖励基数(
rewardBaseCalAmount)和要分配的金额(rewardAmount) - 在无效回合或预言机中断期间保护资金,并在必要时允许退款
以下各节按顺序组织了回合生命周期、Pyth 集成、安全机制和奖励算法。
回合生命周期
每个回合有三个阶段,开始 → 锁定 → 结束,每个阶段都由 intervalSeconds 分隔。投注窗口从 startTimestamp 到 lockTimestamp,价格观察到 closeTimestamp,executeRound 将系统推进到下一步。

- 调用
genesisStartRound和genesisLockRound各一次以引导第一个回合。 - 创世之后,
executeRound在一个事务中为第 n 回合处理三个操作:- 使用最新的预言机价格锁定第 n-1 回合。
- 结束第 n-2 回合并确定其最终价格。
- 为新的投注开启第 n 回合。
- 为允许即使在连续调用延迟时也能安全暂停,工厂强制执行全局
bufferSeconds。任何未在bufferSeconds内完成的阶段都将被拒绝。
Pyth 预言机集成和回退
_getPriceFromOracle 依赖于 Pyth 的 getPriceNoOlderThan,因此只接受在 bufferSeconds 内发布的价格。安全性通过以下方式确保:
- 将发布时间(
publishTime)存储为oracleLatestRoundId,防止操作员意外使用过时数据 - 将 Pyth 的
expo规范化为PYTH_PRICE_DECIMALS (=8)并为负值添加溢出检查 - 每当无法获取价格或更新延迟超过
bufferSeconds时,将oracleCalled保持为false,这将触发稍后描述的退款路径

当价格检索失败时,该回合被标记为“丢失”。因为它永远不满足 claimable 条件,投注者可以通过 refundable 路径全额取回他们的赌注。操作员可以通过调用 pause/unpause 或重播创世步骤来安全地恢复。
投注接收和状态管理
betBull和betBear受whenNotPaused和nonReentrant保护,notContract修饰符仅限 EOA 访问。- 对于每个回合,赌注被添加到
round.totalAmount和特定方向的桶(bullAmount/bearAmount)中;禁止在同一回合内混合头寸。 - 投注必须大于或等于
factory.minBetAmount()以阻止粉尘垃圾邮件。 ledger[epoch][user]存储投注amount及其claimed状态,两者都可以通过getUserRounds进行分页。- 如果一个回合以
oracleCalled == false结束,用户可以在block.timestamp > closeTimestamp + bufferSeconds后请求退款。
奖励计算算法
当操作员调用 executeRound 时,第 n-2 回合的奖励被最终确定。合约使用以下方程式:
treasuryAmt = total * treasuryFee / 10000
rewardAmount = total - treasuryAmt
rewardBaseCalAmount = closePrice > lockPrice ? bullAmount : bearAmount
treasuryFee、treasuryFeeWithReferral和referralFee在工厂级别配置(参见hyperpredict-contract-v1/config/HyperPredictV1Factory.ts)。在 BSC 上,这些值分别为3%、1%和1%。- 当
closePrice == lockPrice(平局)时,rewardAmount变为 0,所有人都会收到退款。 - 获胜玩家的基础赔付是
userAmount / rewardBaseCalAmount * rewardAmount。即使投注者后来有资格获得推荐回扣,此方程式也始终使用treasuryFee(在 BSC 上为 3%),以保持链上数学的确定性。 - 当一个回合无效时,
_calculateRewards会提前退出,并且彩池是可退款的。
推荐分配
推荐处理被推迟到领取时,并且仅当投注者有注册的推荐人时才在 _applyReferralBonus 内部运行:
referralFee(1%) 定义了资助推荐人的资金池。用户的份额是referrerBonus = total * referralFee / 10000 * userBet / rewardBaseCalAmount,它从获胜者的赔付中减去并转移给推荐人。- 为了抵消该减法并使国库在存在推荐时有效地只收取
treasuryFeeWithReferral(1%),获胜者还会收到回扣。回扣池是(treasuryFee - treasuryFeeWithReferral)(在 BSC 上为 2%),获胜者的部分是winnerBonus = total * (treasuryFee - treasuryFeeWithReferral) / 10000 * userBet / rewardBaseCalAmount。此金额在执行领取时从累积的国库余额中扣除。 - 支付给投注者的最终奖励是
baseReward + winnerBonus - referrerBonus。当没有推荐人时,_applyReferralBonus会提前退出,投注者只收到baseReward,因此国库保留全部 3%。
这种延迟计算确保有推荐的投注者最终会使用更便宜的费用计划(1% 国库费 + 1% 推荐费),而没有推荐的投注者则保持 3% 的固定国库费。
领取时执行
当用户调用 claim 时,_claim 按顺序评估每个 epoch:
- 如果
oracleCalled == true且条目是claimable,则计算获胜方的baseReward。 - 运行
_applyReferralBonus以结算推荐分割并最终确定winnerBonus以及任何推荐人奖励。 - 如果在
refundable成立的情况下oracleCalled == false,则只需返回原始赌注。 - 对每个
addedReward求和,以原生货币发送总额,如果累积了推荐奖金,则在单独的转账中发送这些奖金,同时发出ReferralPaid。
具体例子
A: 在牛市上投注 100 USDC
B: 在熊市上投注 100 USDC
C: 推荐人 (邀请了 A)
treasuryFee = 3%
treasuryFeeWithReferral = 1%
referralFee = 1%
回合结果: 牛市获胜
totalAmount = 200 USDCtreasuryAmount (初始) = 200 * 0.03 = 6 USDCrewardAmount = 200 - 6 = 194 USDCrewardBaseCalAmount = bullAmount = 100 USDC- A 的
baseReward = 100 / 100 * 194 = 194 USDC - 推荐池
referralPool = 200 * 0.01 = 2 USDC所以referrerBonus = 2 USDC - 国库回扣池
treasuryRefundPool = 200 * (0.03 - 0.01) = 4 USDC所以winnerBonus = 4 USDC - 获胜者收到
194 + 4 - 2 = 196 USDC - 推荐人收到
2 USDC - 国库保留
6 - 4 = 2 USDC,这与推荐投注的 1% 计划相符
如果投注者没有推荐人,_applyReferralBonus 将完全跳过回扣路径:A 将只领取 194 USDC 的 baseReward,国库将保留全部 3%(6 USDC)。B 仍然会输,因为他们的头寸在金钱之外完成,除非预言机失败,在这种情况下,双方都可以退还他们的赌注。
安全和故障保护
- 角色分离:
onlyOperator驱动回合进程,而onlyAdmin处理国库操作(claimTreasury、recoverToken)。 - 可暂停 + 创世: 异常情况可以通过
pause暂停,然后通过genesisStartRound/genesisLockRound清理重启,避免重复或未定义的回合。 - ReentrancyGuard 和非合约门: 包括赔付路径在内的每个函数都是非重入的,并且只允许 EOA,从而阻止了多重调用合约。
- 缓冲区强制:
_safeLockRound和_safeEndRound拒绝bufferSeconds之外的操作,从而阻止了时间游戏和价格操纵。 - 资金保护:
claimable/refundable条件在预言机停机期间防止双重领取,同时保证本金返还。 - 预言机输入验证:
getPriceNoOlderThan会丢弃过时数据并清理负值或溢出情况。
这些机制共同确保 HyperPredictV1Pair 能够安全、自主地运行完全在链上的预测市场,并具有透明的赔付和推荐核算。