> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Mathématiques d'AMM v4

> Invariant de produit constant avec la convention de frais d'AMM v4, conversion prix réserves-carnet d'ordres, construction de grille d'ordres cibles, et l'étape de règlement PnL.

<Info>
  **Cette page est traduite automatiquement par IA. La version anglaise fait foi.**

  [Voir la version anglaise →](/products/amm-v4/math)
</Info>

## L'invariant

Le pool maintient `coin_reserve × pc_reserve = k`, où (après la suppression d'OpenBook en 2026-07) :

```
coin_reserve = coin_vault_balance - accrued_pnl_coin
pc_reserve   = pc_vault_balance   - accrued_pnl_pc
```

Deux points à noter :

1. Les réserves sont maintenant **limitées aux coffres**. Le terme historique des ordres ouverts (jetons que le pool avait bloqués en tant qu'ordres limités OpenBook) a été supprimé — il était zéro en pratique bien avant la suppression. Vous pouvez calculer `k` directement à partir des soldes des coffres on-chain.
2. L'accumulation de PnL (`need_take_pnl_*`) est soustraite pour que la courbe soit conservée lorsque l'administrateur récupère les frais. Même principe que l'exclusion `protocol_fees_*` du CPMM.

Le programme calcule cela via `calc_total_without_take_pnl_no_orderbook` (l'ancienne variante consciente du carnet d'ordres a disparu).

Chaque opération `Swap*` applique `k' ≥ k` après avoir rajouté la part de frais du LP dans les réserves.

## Convention de frais

AMM v4 utilise des **frais en ratio** (paires numérateur/dénominateur) plutôt que la convention `1/1_000_000` du CPMM / CLMM. La structure `Fees` on-chain (voir [`Fees::initialize`](https://github.com/raydium-io/raydium-amm/blob/master/program/src/state.rs) dans le code source du programme) utilise par défaut :

```
Fees {
  min_separate_numerator:    5,
  min_separate_denominator:  10_000,   //  5/10_000 = 0.05%

  trade_fee_numerator:      25,
  trade_fee_denominator:    10_000,    // 25/10_000 = 0.25% — utilisé pour la tarification des ordres limités OpenBook

  pnl_numerator:            12,
  pnl_denominator:          100,       // 12/100   = 12%   — part du protocole DU frais de swap

  swap_fee_numerator:       25,
  swap_fee_denominator:     10_000,    // 25/10_000 = 0.25% — frais bruts sur les swaps via AMM
}
```

Interprétation (valeurs par défaut publiées sur mainnet) :

* **Frais de swap total :** `swap_fee = amount_in × 25 / 10_000 = 0.25%` de l'entrée brute.
* **Part du protocole :** `pnl_numerator / pnl_denominator = 12 / 100 = 12%` **du frais de swap**, ce qui représente `0.25% × 12% = 0.03%` du volume. Cette part s'accumule dans les compteurs PnL et est récupérée par `WithdrawPnl`.
* **Part du LP :** les `88%` restants du frais de swap, ce qui représente `0.25% × 88% = 0.22%` du volume. Reste dans le pool et augmente `k`.
* **Pas de part de fonds.** AMM v4 n'a pas la division de frais de fonds du CPMM/CLMM.

Notez que `pnl_numerator / pnl_denominator` est une fraction **du frais**, non du volume de trading — une lecture courante erronée de ces noms de champs.

`trade_fee_numerator / trade_fee_denominator` (également `25 / 10_000`) était historiquement utilisé par l'intégration OpenBook lors du calcul des prix incluant les frais pour la grille d'ordres limités du AMM. Avec le code OpenBook supprimé, ce champ est vestigial ; le frais de swap actif est `swap_fee_*`.

Les écarts par rapport à ces valeurs par défaut sont rares mais existent sur quelques pools hérités ; lisez toujours les frais depuis `AmmInfo.fees` avant de faire une cotation.

## Mathématiques de swap direct (chemin AMM)

Le cas le plus simple : l'utilisateur échange contre les coffres du pool sans interagir avec OpenBook. Les réserves internes du pool (y compris les allocations on-book) sont le dénominateur.

**SwapBaseIn (entrée exacte) :**

```
amount_after_fee = amount_in − ceil(amount_in × swap_fee_numerator / swap_fee_denominator)
amount_out = amount_after_fee × out_reserve
           / (in_reserve + amount_after_fee)
require(amount_out >= minimum_amount_out)
```

Les réserves utilisées ici sont les soldes des coffres (moins le PnL accumulé). Historiquement, la formule ajoutait également les jetons que le AMM avait verrouillés dans les ordres OpenBook ; **ce terme a été supprimé** — les réserves effectives égalent maintenant les soldes bruts des coffres moins le PnL en attente. Le chemin `MonitorStep` / règlement implicite qui avait l'habitude de rafraîchir le côté OpenBook a été supprimé.

**SwapBaseOut (sortie exacte) :**

```
amount_in_after_fee = ceil(in_reserve × amount_out / (out_reserve − amount_out))
amount_in_gross     = ceil(amount_in_after_fee × swap_fee_denominator
                            / (swap_fee_denominator − swap_fee_numerator))
require(amount_in_gross <= maximum_amount_in)
```

## Interaction avec le carnet d'ordres (historique)

<Note>
  **Supprimé.** La construction de grille décrite dans cette section reflète comment AMM v4 *à l'origine* miroir la courbe sur un marché OpenBook. L'intégration OpenBook — y compris la manivelle `MonitorStep` et la logique de grille `build_orders` — a été **supprimée du programme** (mise à jour 2026-07). Les mathématiques ci-dessous sont conservées purement comme contexte historique pour ce que les comptes on-chain `target_orders` / `amm_open_orders` étaient autrefois dimensionnés.
</Note>

Séparément des swaps utilisateur, AMM v4 plaçait historiquement une **grille** d'ordres limités sur le marché OpenBook. La grille était calculée à partir des paramètres `AmmInfo` :

* **`depth`** — nombre de niveaux de prix par côté.
* **`amount_wave`** — unité de base de taille par niveau.
* **`min_size`**, **`coin_lot_size`**, **`pc_lot_size`** — contraintes du marché OpenBook.
* **`state_data.swap_acc_coin_fee`**, **`swap_acc_pc_fee`** — compteurs de frais cumulatifs depuis le dernier `TakePnl`.

Le programme dérive les prix par niveau en marchant à partir du prix de courbe actuel par étapes de ratio constant :

```
price_level(k) = curve_price × (1.0001 ^ k)       # conceptuellement
size_level(k)  = amount_wave × f(depth, k)        # effilé par depth
```

Les prix et tailles exacts sont déterminés par `target_orders` calculés dans `build_orders` et comparés avec `amm_open_orders` à chaque `MonitorStep`. Toute divergence entraîne des annulations + nouvelles publications. Les ordres fraîchement remplis sur OpenBook se règlent dans les coffres du pool lors de la prochaine opération qui rafraîchit le côté OpenBook.

Les intégrateurs ont rarement besoin de calculer la grille — le gardien Raydium la maintient — mais il est utile de savoir que :

* Un pool avec une liquidité **on-book** significative a cette liquidité contribuant à `k`, pas inactif.
* Un marché OpenBook obsolète (file d'événements pleine, manivelles bloquées) empêche les mises à jour de grille ; le AMM peut alors citer des prix qui divergent du carnet d'ordres visible jusqu'à la prochaine manivelle.

## Étape de règlement (PnL)

La part du protocole de 0.03% s'accumule dans `state_data.need_take_pnl_coin` et `state_data.need_take_pnl_pc`. `TakePnl` déplace ces montants hors des coffres vers la destination spécifiée par l'administrateur, puis remet les compteurs à zéro.

Propriété cruciale : les réserves dans l'invariant sont toujours calculées **moins** le PnL accumulé, donc `TakePnl` ne déplace pas la courbe. Cela correspond à la convention CPMM.

## Exemple travaillé

État du pool :

* `coin_reserve = 1_000_000_000_000` (1 000 000 côté coin ; 6 décimales)
* `pc_reserve   = 2_000_000_000_000` (2 000 000 côté pc ; 6 décimales)
* Frais : `swap = 25/10_000` par défaut, `pnl = 3/10_000`.

Utilisateur : `SwapBaseIn` entrée exacte `1_000_000_000` coin (1 000 coin).

```
swap_fee        = ceil(1_000_000_000 * 25 / 10_000)    = 2_500_000
amount_after_fee =                                      997_500_000

amount_out = amount_after_fee * pc_reserve
           / (coin_reserve + amount_after_fee)
           = 997_500_000 * 2_000_000_000_000
           / (1_000_000_000_000 + 997_500_000)
           ≈ 1_995_015_009  (1 995,015 pc)

// Des 2_500_000 frais de swap :
pnl_share = 2_500_000 * 3 / 25  = 300_000    (va au protocole via need_take_pnl_coin)
lp_share  = 2_500_000 * 22 / 25 = 2_200_000  (reste dans coin_reserve)

new coin_reserve = 1_000_000_000_000 + 1_000_000_000                 = 1_001_000_000_000
                   (dont 300_000 est du PnL accumulé)
  curve coin_reserve = 1_001_000_000_000 − 300_000 = 1_000_999_700_000
new pc_reserve   = 2_000_000_000_000 − 1_995_015_009                 ≈ 1_998_004_984_991

k' = curve_coin_reserve * new_pc_reserve
   ≈ 2.000_002_701E24
k  = 1_000_000_000_000 * 2_000_000_000_000
   = 2.0E24
k' > k   ✓
```

La part du LP (`2_200_000`) n'est pas détaillée nulle part — c'est simplement le résidu qui augmente `k'`.

## Règles de précision

* Les multiplications de réserves utilisent `u128` ; les divisions finales arrondissent vers zéro.
* `swap_fee` arrondit vers le haut (pour que le pool ne sous-facture pas).
* `amount_in` pour `SwapBaseOut` arrondit vers le haut (pour que l'utilisateur ne sous-paie pas).
* Les pools avec des ratios de réserve extrêmes peuvent atteindre `ZeroTradingTokens` sur très petites entrées ; même convention que CPMM.

## Limitations par rapport au CPMM

* Les réserves d'AMM v4 sont maintenant limitées aux coffres, donc vous **pouvez** citer directement à partir des soldes des coffres (moins `need_take_pnl_*`) — l'exigence précédente d'ajouter les montants `open_orders.free` / `open_orders.locked` ne s'applique plus. La cotation SDK / API reste l'option la plus simple.
* AMM v4 n'expose pas un TWAP structuré on-chain. Les consommateurs externes qui veulent un prix soutenu par AMM-v4 doivent le calculer eux-mêmes à partir des journaux de trading.
* Token-2022 n'est pas supporté.

## Où aller ensuite

* [`products/amm-v4/instructions`](/fr/products/amm-v4/instructions) — où `SwapBaseIn`, `Deposit`, etc. s'intègrent.
* [`products/amm-v4/fees`](/fr/products/amm-v4/fees) — mécanique complète des frais, détails de `TakePnl`.
* [`algorithms/constant-product`](/fr/algorithms/constant-product) — la dérivation partagée.

Sources :

* [Code source du programme Raydium AMM — `raydium-io/raydium-amm`](https://github.com/raydium-io/raydium-amm)
* Module `Liquidity` du SDK Raydium v2
