XP, Yield matching, Carry YELD payout

Cette section décrit la mécanique Yield dans le backend actuel (le module technique interne s'appelle yield).

1) Termes (dans le système actuel)

  • XP : dans ce document nous l'appelons XP. Dans le backend, le nom interne est xp (models/fields : XPCredit, carryLeftXP, carryRightXP).
  • USDOL/USDOR : ce sont les branches LEFT/RIGHT (yield sides).
  • Carry YELD : stocké dans le backend sous carryYeldUsdo (base USDO) et signifie le payout pool accumulé via le yield matching, qui est ensuite payé avec des caps hebdomadaires.

2) Calcul XP à partir d'un investissement

  • Pour chaque investissement, XP est calculé comme suit :
    • xpBase = amountBase * xpPercent / 100
    • xpPercent vient des paramètres Block (par défaut : 20%)

3) Propagation XP dans l'arbre

Un investissement a un placement side (LEFT ou RIGHT) basé sur investmentInviteCode :

  • L'utilisateur de placement peut recevoir un crédit XP sur le même côté
  • Ensuite, le crédit XP “monte” via la chaîne referredByUserId jusqu'à la root (max depth guard=100)

4) Limitation importante : seuls les utilisateurs TIP3 reçoivent des crédits XP

Dans le système actuel :

  • Un crédit XP est créé uniquement si le programTier === TIP3 du destinataire.
  • La même garde existe dans le yield worker (module interne yield) : si le credit receiver n'est pas TIP3, le crédit est simplement marqué comme traité sans modifier carry.

Cela signifie :

  • Les utilisateurs TIP1/TIP2 n'accumulent pas carryLeft/carryRight (yield carry).
  • Les investissements TIP1/TIP2 peuvent “créer” des XP, mais le crédit XP réel est reçu uniquement par l'ancestor/nœud de placement qui est TIP3.

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

Le yield worker fonctionne sur les enregistrements XPCredit (nom interne : xp).

  • Chaque crédit augmente carryLeft ou carryRight.
  • La taille de paire est fixe : 10 XP.
  • Pour chaque paire appariée, le payout est fixe : 10 USDO.
  • Après matching, les carries diminuent et le payout est ajouté à carryYeldUsdo.

6) Cap de payout hebdomadaire (Reward levels)

carryYeldUsdo ne “devient pas solde” instantanément. Le paiement est effectué par le job payoutCarryYeld :

  • Chaque utilisateur a un reward level (1..4) dans userRewardStatus.
  • Chaque niveau a un payout max hebdomadaire (par défaut) :
    • L1 : 2000 USDO/semaine
    • L2 : 4000 USDO/semaine
    • L3 : 6000 USDO/semaine
    • L4 : 8000 USDO/semaine
  • Si le carryYeld de l'utilisateur dépasse l'allocation hebdomadaire restante, l'excédent est burned (non payé).
  • Le suivi du payout hebdomadaire est stocké via yieldAccount.weeklyPayoutUsdo + weekKey.

7) Auto payout schedule

  • Si les paramètres Block ont yieldAutoPayoutEnabled=true, un repeat job payoutCarryYeld est ajouté à la queue avec un cron pattern (dayOfWeek/hour/minute).
  • Si désactivé, le repeat job est supprimé en mode best-effort.

8) Effet d'un upgrade TIP sur carry

Quand le tier global d'un utilisateur augmente :

  • Les crédits XP en attente sont marqués comme traités pour éviter un payout depuis l'ancien état.
  • yieldAccount.carryLeftXP/carryRightXP sont réinitialisés à 0.
  • Dans le flux de création d'investissement, carryYeldUsdo est aussi réinitialisé à 0 (sauf dans l'endpoint upgrade, où seul le carry left/right est réinitialisé).