> ## 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.

# Matematika AMM v4

> Invariant constant-product dengan konvensi biaya AMM v4, konversi harga reserve-ke-orderbook, konstruksi grid order target, dan langkah settlement PnL.

<Info>
  **Halaman ini diterjemahkan secara otomatis oleh AI. Versi bahasa Inggris adalah acuan resmi.**

  [Lihat versi bahasa Inggris →](/products/amm-v4/math)
</Info>

## Invariant

Pool mempertahankan `coin_reserve × pc_reserve = k`, di mana (setelah penghapusan OpenBook 2026-07):

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

Dua hal yang perlu diperhatikan:

1. Reserve sekarang **vault-only**. Istilah open-order historis (token yang pool escrow sebagai limit order OpenBook) telah dihapus — nilainya sudah nol dalam praktik jauh sebelum penghapusan. Anda dapat menghitung `k` langsung dari saldo vault on-chain.
2. Akrual PnL (`need_take_pnl_*`) dikurangi sehingga kurva terjaga ketika admin menyapu biaya. Prinsip yang sama dengan pengecualian `protocol_fees_*` CPMM.

Program menghitung ini melalui `calc_total_without_take_pnl_no_orderbook` (varian lama yang aware orderbook sudah hilang).

Setiap operasi `Swap*` menegakkan `k' ≥ k` setelah menambahkan bagian biaya LP kembali ke reserve.

## Konvensi biaya

AMM v4 menggunakan **ratio fees** (pasangan numerator/denominator) daripada konvensi `1/1_000_000` dari CPMM / CLMM. Struct `Fees` on-chain (lihat [`Fees::initialize`](https://github.com/raydium-io/raydium-amm/blob/master/program/src/state.rs) dalam sumber program) default ke:

```
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% — digunakan untuk pricing limit-order OpenBook

  pnl_numerator:            12,
  pnl_denominator:          100,       // 12/100   = 12%   — bagian protokol DARI biaya swap

  swap_fee_numerator:       25,
  swap_fee_denominator:     10_000,    // 25/10_000 = 0.25% — biaya kotor pada swap jalur AMM
}
```

Interpretasi (default mainnet yang dipublikasikan):

* **Total biaya swap:** `swap_fee = amount_in × 25 / 10_000 = 0.25%` dari input kotor.
* **Bagian protokol:** `pnl_numerator / pnl_denominator = 12 / 100 = 12%` **dari biaya swap**, yang menghasilkan `0.25% × 12% = 0.03%` dari volume. Bagian ini terakrual ke counter PnL dan disapu oleh `WithdrawPnl`.
* **Bagian LP:** sisa `88%` dari biaya swap, yang menghasilkan `0.25% × 88% = 0.22%` dari volume. Tetap di pool dan menginflasi `k`.
* **Tidak ada bagian dana.** AMM v4 tidak memiliki pemisahan biaya dana CPMM/CLMM.

Perhatikan bahwa `pnl_numerator / pnl_denominator` adalah fraksi **dari biaya**, bukan dari volume perdagangan — kesalahpahaman umum dari nama field ini.

`trade_fee_numerator / trade_fee_denominator` (juga `25 / 10_000`) secara historis digunakan oleh integrasi OpenBook saat menghitung harga inclusive-fee untuk grid limit-order AMM. Dengan kode OpenBook dihapus, field ini vestigial; biaya swap aktif adalah `swap_fee_*`.

Penyimpangan dari default ini jarang terjadi tetapi ada di beberapa pool legacy; selalu baca biaya dari `AmmInfo.fees` sebelum memberikan penawaran.

## Matematika swap langsung (jalur AMM)

Kasus paling sederhana: pengguna swap terhadap vault pool tanpa berinteraksi dengan OpenBook. Reserve internal pool (termasuk alokasi on-book) adalah denominator.

**SwapBaseIn (input tepat):**

```
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)
```

Reserve yang digunakan di sini adalah saldo vault (minus PnL terakrual). Secara historis formula juga menambahkan token yang AMM kunci ke order OpenBook; **istilah itu telah dihapus** — reserve efektif sekarang sama dengan saldo vault mentah dikurangi PnL pending. Jalur `MonitorStep` / implicit-settle yang dulu menyegarkan sisi OpenBook telah dihapus.

**SwapBaseOut (output tepat):**

```
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)
```

## Interaksi order-book (historis)

<Note>
  **Dihapus.** Konstruksi grid yang dijelaskan di bagian ini mencerminkan bagaimana AMM v4 *awalnya* mencerminkan kurva ke pasar OpenBook. Integrasi OpenBook — termasuk crank `MonitorStep` dan logika grid `build_orders` — telah **dihapus dari program** (upgrade 2026-07). Matematika di bawah dipertahankan murni sebagai konteks historis untuk apa yang pernah diskalakan akun on-chain `target_orders` / `amm_open_orders`.
</Note>

Terpisah dari swap pengguna, AMM v4 secara historis menempatkan **grid** limit order di pasar OpenBook. Grid dihitung dari parameter `AmmInfo`:

* **`depth`** — jumlah level harga per sisi.
* **`amount_wave`** — unit dasar ukuran per level.
* **`min_size`**, **`coin_lot_size`**, **`pc_lot_size`** — batasan pasar OpenBook.
* **`state_data.swap_acc_coin_fee`**, **`swap_acc_pc_fee`** — counter biaya kumulatif sejak `TakePnl` terakhir.

Program menurunkan harga per-level dengan berjalan keluar dari harga kurva saat ini dalam langkah rasio konstan:

```
price_level(k) = curve_price × (1.0001 ^ k)       # secara konseptual
size_level(k)  = amount_wave × f(depth, k)        # taper oleh depth
```

Harga dan ukuran eksak ditentukan oleh `target_orders` yang dihitung dalam `build_orders` dan dibandingkan dengan `amm_open_orders` setiap `MonitorStep`. Setiap perbedaan menghasilkan pembatalan + posting baru. Order yang baru terisi di OpenBook settle ke vault pool pada operasi berikutnya yang menyegarkan sisi OpenBook.

Integrator jarang perlu menghitung grid — keeper Raydium mempertahankannya — tetapi berguna untuk mengetahui bahwa:

* Pool dengan likuiditas **on-book** signifikan memiliki likuiditas itu berkontribusi ke `k`, bukan idle.
* Pasar OpenBook yang stale (event queue penuh, crank terblokir) mencegah update grid; AMM kemudian dapat mengutip harga yang menyimpang dari order book yang terlihat sampai crank berikutnya.

## Langkah settlement (PnL)

Bagian protokol 0.03% terakrual ke `state_data.need_take_pnl_coin` dan `state_data.need_take_pnl_pc`. `TakePnl` memindahkan jumlah ini keluar dari vault ke destinasi yang ditentukan admin, kemudian menolkan counter.

Properti krusial: reserve dalam invariant selalu dihitung **minus** PnL terakrual, jadi `TakePnl` tidak menggerakkan kurva. Ini cocok dengan konvensi CPMM.

## Contoh kerja

State pool:

* `coin_reserve = 1_000_000_000_000` (1.000.000 coin-side; 6 desimal)
* `pc_reserve   = 2_000_000_000_000` (2.000.000 pc-side; 6 desimal)
* Biaya: default `swap = 25/10_000`, `pnl = 3/10_000`.

Pengguna: `SwapBaseIn` input-tepat `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)

// Dari biaya swap 2_500_000:
pnl_share = 2_500_000 * 3 / 25  = 300_000    (ke protokol via need_take_pnl_coin)
lp_share  = 2_500_000 * 22 / 25 = 2_200_000  (tetap di coin_reserve)

new coin_reserve = 1_000_000_000_000 + 1_000_000_000                 = 1_001_000_000_000
                   (di mana 300_000 adalah PnL terakrual)
  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   ✓
```

Bagian LP (`2_200_000`) tidak dipecah di mana pun — itu hanya residual yang menaikkan `k'`.

## Aturan presisi

* Perkalian reserve menggunakan `u128`; pembagian final pembulatan menuju nol.
* `swap_fee` pembulatan naik (sehingga pool tidak undercharge).
* `amount_in` untuk `SwapBaseOut` pembulatan naik (sehingga pengguna tidak underpay).
* Pool dengan rasio reserve ekstrem dapat hit `ZeroTradingTokens` pada input sangat kecil; konvensi yang sama seperti CPMM.

## Keterbatasan vs CPMM

* Reserve AMM v4 sekarang vault-only, jadi Anda **dapat** mengutip langsung dari saldo vault (minus `need_take_pnl_*`) — persyaratan sebelumnya untuk menambahkan jumlah `open_orders.free` / `open_orders.locked` tidak lagi berlaku. Kutipan SDK / API tetap menjadi opsi paling sederhana.
* AMM v4 tidak mengekspos TWAP terstruktur on-chain. Konsumen eksternal yang menginginkan harga yang didukung AMM-v4 harus menghitungnya sendiri dari log perdagangan.
* Token-2022 tidak didukung.

## Ke mana selanjutnya

* [`products/amm-v4/instructions`](/id/products/amm-v4/instructions) — di mana `SwapBaseIn`, `Deposit`, dll. terhubung.
* [`products/amm-v4/fees`](/id/products/amm-v4/fees) — mekanik biaya penuh, detail `TakePnl`.
* [`algorithms/constant-product`](/id/algorithms/constant-product) — derivasi bersama.

Sumber:

* [Sumber program Raydium AMM — `raydium-io/raydium-amm`](https://github.com/raydium-io/raydium-amm)
* Modul `Liquidity` Raydium SDK v2
