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

# AMM constant-product

> Invariant x·y=k, penetapan harga berbasis cadangan, derivasi slippage, dan varian penanganan fee yang digunakan oleh Raydium CPMM dan AMM v4. Ini adalah halaman referensi math yang menjadi acuan untuk setiap produk x·y=k di Raydium.

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

  [Lihat versi bahasa Inggris →](/algorithms/constant-product)
</Info>

## Invariant

Constant-product market maker (CPMM) memegang dua cadangan `x` dan `y` dan menjamin:

```
x · y ≥ k       (setelah setiap trade)
```

dengan `k` adalah produk dari cadangan sebelum trade. Untuk market tanpa fee, `x · y = k` tepat. Dengan fee, `k` tumbuh ketat (bagian LP dari fee disimpan dalam cadangan).

Invariant dirancang secara geometris: menjamin bahwa tidak peduli seberapa kecil satu cadangan, cadangan lainnya tumbuh tanpa batas untuk menyamai — artinya pool tidak pernah bisa habis di satu sisi.

## Penetapan harga

### Harga spot

Harga marginal `y` yang dinyatakan dalam `x` pada saat apa pun adalah garis singgung kurva:

```
p = y / x
```

(derivasi: diferensiasi implisit dari `x · y = k` memberikan `dy/dx = −y/x`; abaikan tanda, `|dy/dx| = y/x`).

Ini adalah harga yang dikutip pool untuk trade yang sangat kecil. Untuk trade berdimensi nyata, harga yang terealisasi lebih buruk karena slippage sepanjang kurva.

### Swap dengan input tepat (berikan `Δx`, terima `Δy`)

Dengan fee, misalkan `f` adalah tarif fee (contoh `f = 0.0025` untuk 25 bps). Terapkan fee pada input, kemudian gunakan invariant untuk menyelesaikan output:

```
Δx_after_fee = Δx · (1 − f)
Δy           = y · Δx_after_fee / (x + Δx_after_fee)
```

Cadangan setelah trade:

```
x' = x + Δx
y' = y − Δy
```

`Δx` penuh masuk ke dalam cadangan. Bagian LP dari fee tetap dalam `x'`; bagian protokol dikecualikan dari kurva melalui langkah akuntansi terpisah (lihat [Varian akuntansi fee](#fee-accounting-variants) di bawah).

### Swap dengan output tepat (terima `Δy`, bayar minimal `Δx`)

```
Δx_after_fee = x · Δy / (y − Δy)
Δx           = Δx_after_fee / (1 − f)
```

`Δx` dibulatkan ke atas untuk memastikan pool tidak mengalami kerugian biaya.

## Slippage dan dampak harga

**Dampak harga** mengukur berapa banyak harga spot pool bergerak sebagai hasil dari trade:

```
p_before = y / x
p_after  = y' / x' = (y − Δy) / (x + Δx)
impact   = (p_before − p_after) / p_before
```

Untuk `Δx / x` kecil, ekspansi tingkat pertama memberikan:

```
impact ≈ 2 · Δx / x      (mengabaikan fee)
```

Intuisi: swap 1% menyebabkan dampak harga \~2%. Faktor 2 ini adalah alasan pool CPMM yang dikutip untuk trade ukuran sedang terlihat "tipis" dibandingkan pasar orderbook — Anda tidak hanya membeli terhadap bid terbaik saat ini, tetapi juga berjalan naik harga marginal Anda sendiri.

**Harga efektif** yang dibayar oleh swapper:

```
effective = Δx / Δy
```

Spread antara `p_before` dan `effective` adalah **slippage**. Slippage UI on-chain biasanya dinyatakan sebagai `(effective − p_before) / p_before`; SDK `computeAmountOut` mengembalikan baik `amountOut` maupun `priceImpact` karena alasan ini.

## Pemeriksaan invariant dalam kode

Setelah swap, protokol memverifikasi ulang:

```
k' = x' · y'  ≥  k  =  x · y
```

Pelanggaran apa pun adalah bug program atau overflow aritmetika. Instruksi swap Raydium membuat pemeriksaan ini eksplisit sebagai pasca-syarat:

```rust theme={null}
let k_before = coin_reserve_before as u128 * pc_reserve_before as u128;
let k_after  = coin_reserve_after  as u128 * pc_reserve_after  as u128;
require!(k_after >= k_before, ErrorCode::InvariantViolation);
```

## Varian akuntansi fee

Pemeriksaan invariant mengasumsikan fee LP tetap dalam cadangan. Produk Raydium yang berbeda menangani komponen protokol / dana / kreator secara berbeda:

### Konvensi CPMM

Fee adalah tarif basis-point-like `u64` pada penyebut `1_000_000`. Fee trade dibagi menjadi `trade_fee_rate` (total) kemudian dibagi melalui `protocol_fee_rate`, `fund_fee_rate`, `creator_fee_rate`. Pada setiap swap:

```
trade_fee     = ceil(Δx · trade_fee_rate / 1_000_000)
protocol_fee  = trade_fee · protocol_fee_rate / 1_000_000
fund_fee      = trade_fee · fund_fee_rate     / 1_000_000
creator_fee   = trade_fee · creator_fee_rate  / 1_000_000
lp_fee        = trade_fee − protocol_fee − fund_fee − creator_fee
```

Tiga bagian non-LP terakumulasi dalam penghitung terpisah (`protocol_fees_*`, `fund_fees_*`, `creator_fees_*`) yang **dikecualikan** dari cadangan yang digunakan dalam invariant. Ini adalah cara fee dapat disapu tanpa menggerakkan kurva. Lihat [`products/cpmm/fees`](/id/products/cpmm/fees).

### Konvensi AMM v4

Fee adalah rasio `numerator / denominator` pada penyebut `10_000`. Pembagian ditetapkan pada saat pembuatan pool dan disimpan pada `AmmInfo.fees`:

```
swap_fee  = ceil(Δx · swap_fee_numerator / swap_fee_denominator)    // contoh 0.25%
pnl_share = swap_fee · pnl_numerator / swap_fee_numerator            // contoh 0.03 / 0.25 = 12%
lp_share  = swap_fee − pnl_share                                     // 0.22% dari volume
```

`pnl_share` terakumulasi dalam `state_data.need_take_pnl_*` dan dikecualikan dari cadangan; `lp_share` tetap dalam vault. Lihat [`products/amm-v4/fees`](/id/products/amm-v4/fees).

Kedua konvensi mempertahankan invariant dengan cara yang sama — perbedaannya adalah kosmetik (penyebut + jumlah sub-kategori).

## Aturan pembulatan

* **Perhitungan fee dibulatkan ke atas.** Memastikan pool tidak pernah mengalami kerugian fee.
* **Jumlah output dibulatkan ke bawah.** Memastikan invariant berlaku ketat (`k' > k` bahkan sebelum fee ditambahkan).
* **Jumlah input output-tepat dibulatkan ke atas.** Memastikan pengguna tidak kurang membayar.

Semua aritmetika menggunakan `u128` untuk produk `x · Δx` perantara untuk menghindari overflow pada cadangan besar. Hasil akhir dilemparkan kembali ke `u64` dengan pemeriksaan saturasi.

## Kasus tepi

### Pool kosong

Sebelum `Deposit` pertama, `x = y = 0`. Instruksi swap menolak pra-deposit.

### Output nol

Jika `Δx` cukup kecil sehingga `Δy` yang dibulatkan ke bawah adalah 0, instruksi berbalik dengan `ZeroTradingTokens`. Ini mencegah ekstraksi nilai tanpa pembayaran; juga berarti swap dust pada pool yang sangat tidak seimbang gagal.

### LP dust

`Deposit` pertama memiliki penanganan khusus: menghitung pasokan LP awal sebagai `sqrt(x · y)` dan membakar jumlah "init burn" kecil (biasanya 100 unit LP) untuk mencegah "serangan inflasi depositor pertama" (di mana penyerang menyumbang ke vault dan menginflasi nilai token LP). Deposit berikutnya menggunakan math pro-rata.

## Hubungan dengan arbitrase

Harga pool CPMM hanya berubah melalui:

1. Trade melalui pool itu sendiri (pengguna berjalan di kurva).
2. Donasi (mengirim token ke vault tanpa swap).

Karena trade menggerakkan harga secara deterministik dengan kurva, pool apa pun yang harganya divergen dari harga pasar yang lebih luas menciptakan peluang arbitrase. Arbitraser membawa harga pool kembali ke harga pasar sesuai harapan. Inilah mengapa pool CPMM dikatakan "mengutip harga tanpa oracle": pasar menemukan harga melalui arbitrase daripada pool membacanya secara eksternal.

Sisi sebaliknya: pool itu sendiri adalah mitra arbitraser, jadi setiap keuntungan arbitrase adalah LP impermanent loss (minus fee yang ditangkap oleh LP).

## Contoh kerja

### Contoh 1 — trade kecil, slippage yang dapat diabaikan

Pool: `x = 1_000_000, y = 2_000_000, k = 2·10^12`. Fee `f = 0.0025`.

Trade `Δx = 1_000`:

```
Δx_after_fee = 1000 · 0.9975  = 997.5
Δy           = 2_000_000 · 997.5 / (1_000_000 + 997.5)
             = 1_995_000_000 / 1_000_997.5
             ≈ 1_993.01
```

Harga efektif: `1000 / 1993.01 ≈ 0.5018`. Spot sebelumnya: `0.5`. Dampak: \~0.36%.

### Contoh 2 — trade ukuran sedang, slippage terlihat

Pool yang sama, `Δx = 100_000` (10% dari `x`):

```
Δx_after_fee = 100_000 · 0.9975 = 99_750
Δy           = 2_000_000 · 99_750 / (1_000_000 + 99_750)
             = 199_500_000_000 / 1_099_750
             ≈ 181_405
```

Efektif: `100_000 / 181_405 ≈ 0.5513`. Dampak: \~10.3% — kira-kira setengah dari aturan jempol `2 · 10% = 20%` (aturan ini adalah batas ceiling kasus terburuk untuk kurva constant-product tanpa fee; fee trade plus inversi dalam rumus menurunkannya).

## Penunjuk

* [`products/cpmm/math`](/id/products/cpmm/math) — pilihan pembulatan dan penyebut fee spesifik CPMM.
* [`products/amm-v4/math`](/id/products/amm-v4/math) — bagaimana cadangan yang terintegrasi OpenBook AMM v4 memperluas model ini.
* [`algorithms/slippage-and-price-impact`](/id/algorithms/slippage-and-price-impact) — halaman khusus pada sizing toleransi slippage untuk UI.

Sumber:

* Uniswap v2 whitepaper — pernyataan canonical dari `x · y = k`.
* Kode sumber program Raydium CPMM.
* Kode sumber program Raydium AMM v4.
