XP, Yield matching, Carry YELD payout

Esta sección describe la mecánica de Yield en el backend actual (el módulo técnico interno se llama yield).

1) Términos (en el sistema actual)

  • XP: en este documento lo llamamos XP. En el backend, el nombre interno es xp (modelos/campos: XPCredit, carryLeftXP, carryRightXP).
  • USDOL/USDOR: estas son las ramas LEFT/RIGHT (lados de yield).
  • Carry YELD: se almacena en el backend como carryYeldUsdo (base USDO) y significa el pool de payout acumulado a partir del yield matching, que luego se paga con caps semanales.

2) Cálculo de XP desde una inversión

  • Para cada inversión, XP se calcula como:
    • xpBase = amountBase * xpPercent / 100
    • xpPercent proviene de la configuración del Block (por defecto: 20%)

3) Propagación de XP por el árbol

Una inversión tiene un lado de placement (LEFT o RIGHT) según investmentInviteCode:

  • El usuario de placement puede recibir un crédito XP en ese mismo lado
  • Luego el crédito XP “sube” por la cadena referredByUserId hasta la raíz (protección de profundidad máxima=100)

4) Limitación importante: solo usuarios TIP3 reciben créditos XP

En el sistema actual:

  • Se crea un crédito XP solo si el programTier === TIP3 del usuario receptor.
  • La misma protección existe en el worker de yield (módulo interno yield): si el receptor del crédito no es TIP3, el crédito simplemente se marca como procesado sin cambiar el carry.

Esto significa:

  • Los usuarios TIP1/TIP2 no acumulan carryLeft/carryRight (yield carry).
  • Las inversiones TIP1/TIP2 pueden “crear” XP, pero el crédito XP real lo recibe solo el ancestro/nodo de placement que sea TIP3.

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

El worker de yield opera sobre registros XPCredit (nombre interno: xp).

  • Cada crédito incrementa carryLeft o carryRight.
  • El tamaño del par es fijo: 10 XP.
  • Por cada par emparejado, el payout es fijo: 10 USDO.
  • Después del matching, los carries disminuyen y el payout se añade a carryYeldUsdo.

6) Cap semanal de payout (Reward levels)

carryYeldUsdo no “se convierte en saldo” instantáneamente. El pago lo realiza el job payoutCarryYeld:

  • Cada usuario tiene un reward level (1..4) en userRewardStatus.
  • Cada nivel tiene un payout semanal máximo (por defecto):
    • L1: 2000 USDO/semana
    • L2: 4000 USDO/semana
    • L3: 6000 USDO/semana
    • L4: 8000 USDO/semana
  • Si el carryYeld del usuario excede el remanente semanal permitido, el excedente se quema (no se paga).
  • El progreso del payout semanal se guarda usando yieldAccount.weeklyPayoutUsdo + weekKey.

7) Calendario de auto payout

  • Si la configuración de Block tiene yieldAutoPayoutEnabled=true, se añade a la cola un job repetitivo payoutCarryYeld con patrón cron (dayOfWeek/hour/minute).
  • Si está deshabilitado, el repeat job se elimina en modo best-effort.

8) Efecto de la mejora de TIP sobre el carry

Cuando aumenta el tier global de un usuario:

  • Los créditos XP pendientes se marcan como procesados para que no haya payout desde el estado anterior.
  • yieldAccount.carryLeftXP/carryRightXP se restablecen a 0.
  • En el flujo de creación de inversión, carryYeldUsdo también se restablece a 0 (excepto en el endpoint de upgrade, donde solo se restablece el carry left/right).