XP、Yield matching、Carry YELD payout

本节描述当前 backend 中的 Yield 机制(内部技术模块名为 yield)。

1) Terms(当前系统)

  • XP: 本文称其为 XP。在 backend 中内部名为 xp(models/fields: XPCredit, carryLeftXP, carryRightXP)。
  • USDOL/USDOR: 指 LEFT/RIGHT branches(yield sides)。
  • Carry YELD: 在 backend 中存为 carryYeldUsdo(USDO-base),表示由 yield matching 累积的 payout pool,随后按 weekly caps 发放。

2) investment 产生 XP 的计算

  • 每笔 investment 的 XP 计算为:
    • xpBase = amountBase * xpPercent / 100
    • xpPercent 来自 Block settings(default: 20%)

3) XP 在树中的向上传播

investment 基于 investmentInviteCode 具有 placement side(LEFT 或 RIGHT):

  • placement user 可在同一 side 获得 XP credit
  • 然后 XP credit 会沿 referredByUserId 链向上移动到 root(max depth guard=100)

4) 重要限制:只有 TIP3 用户会收到 XP credits

在当前系统中:

  • 仅当接收者用户 programTier === TIP3 时才创建 XP credit。
  • yield worker(内部模块 yield)中也有同样 guard:若接收者不是 TIP3,则该 credit 仅标记为 processed,不改变 carry。

这意味着:

  • TIP1/TIP2 users 不会累积 carryLeft/carryRight(yield carry)。
  • TIP1/TIP2 investments 可能“生成”XP,但实际 XP credit 只会被 TIP3 的祖先/placement 节点接收。

5) Yield matching(10 XP + 10 XP → 10 USDO)

yield worker 基于 XPCredit records(internal name: xp)运行。

  • 每条 credit 会增加 carryLeftcarryRight
  • Pair size 固定:10 XP。
  • 每个 matched pair 的 payout 固定:10 USDO。
  • matching 后,carries 减少,payout 加入 carryYeldUsdo

6) Weekly payout cap(Reward levels)

carryYeldUsdo 不会立即“变成余额”。支付由 payoutCarryYeld job 执行:

  • 每个 user 在 userRewardStatus 中有 reward level(1..4)。
  • 每个 level 的 weekly max payout(defaults):
    • L1: 2000 USDO/week
    • L2: 4000 USDO/week
    • L3: 6000 USDO/week
    • L4: 8000 USDO/week
  • 若用户 carryYeld 超过剩余 weekly allowance,overflow 会被 burned(不发放)。
  • Weekly payout 进度通过 yieldAccount.weeklyPayoutUsdo + weekKey 存储。

7) Auto payout schedule

  • 若 Block settings 中 yieldAutoPayoutEnabled=true,队列会按 cron pattern(dayOfWeek/hour/minute)添加重复任务 payoutCarryYeld
  • 若禁用,则该重复任务会以 best-effort 方式移除。

8) TIP upgrade 对 carry 的影响

当用户 overall tier 提升时:

  • Pending XP credits 会被标记为 processed,避免旧状态继续 payout。
  • yieldAccount.carryLeftXP/carryRightXP 会重置为 0。
  • 在 investment create flow 中,carryYeldUsdo 也会重置为 0(upgrade endpoint 例外,该处仅重置 left/right carry)。