Skip to main content
Halaman ini diterjemahkan secara otomatis oleh AI. Versi bahasa Inggris adalah acuan resmi.Lihat versi bahasa Inggris →

Invariant

CPMM mempertahankan invariant constant-product klasik pada dua vault-nya: xy=kx \cdot y = k di mana x adalah saldo vault0 setelah biaya transfer Token-2022 diterima, dan sama halnya untuk y. Setiap swap harus meninggalkan k' ≥ k setelah memperhitungkan trade fee yang dikreditkan ke LP (bucket protocol, fund, dan creator tidak dihitung menuju k — ada di vault tetapi dikecualikan dari tampilan kurva, lihat Biaya pada kurva di bawah). k oleh karena itu tumbuh secara monoton seiring waktu saat LP mengumpulkan biaya. Saham LP dihargai menurut cadangan pool, bukan menurut k: LP price in token0=xlpSupply,LP price in token1=ylpSupply\text{LP price in token0} = \frac{x}{\text{lpSupply}}, \qquad \text{LP price in token1} = \frac{y}{\text{lpSupply}} Membakar ΔLP token LP mengembalikan tepat ΔLP × x / lpSupply dari token0 dan ΔLP × y / lpSupply dari token1. Kurva dan k tidak bergerak saat deposit atau penarikan — hanya swap yang mengubah harga.

Model biaya pada jalur swap

CPMM menerapkan dua biaya berperingkat independen pada setiap swap:
  • Trade fee diambil di sisi input, dikenakan pada AmmConfig.trade_fee_rate. Kemudian dibagi menjadi saham LP, protocol, dan fund (saham LP tetap di vault dan menumbuhkan k; saham protocol dan fund diekstraksi dari akuntansi vault).
  • Creator fee (aktif hanya ketika enable_creator_fee == true) dikenakan pada AmmConfig.creator_fee_rate. Diambil di sisi input atau sisi output tergantung pada PoolState.creator_fee_on dan arah swap (lihat products/cpmm/fees). Ini adalah bucket sendiri — tidak pernah potongan dari trade fee.
Misalkan:
  • FEE_RATE_DENOMINATOR = 1_000_000
  • trade_fee_rate — dari AmmConfig, misalnya 2500 = 0,25% dari volume sisi yang relevan
  • creator_fee_rate — dari AmmConfig, misalnya 1000 = 0,10% dari volume sisi yang relevan
  • protocol_fee_rate, fund_fee_rate — didenominasikan dalam unit 1/FEE_RATE_DENOMINATOR dari trade fee, bukan dari volume
Ketika creator fee ada di sisi input:
Ketika creator fee ada di sisi output:
Dalam kedua kasus trade fee dibagi dengan cara yang sama:
Jumlah protocol_fee + fund_fee + creator_fee disimpan di vault tetapi dilacak secara terpisah pada pool state (protocol_fees_token*, fund_fees_token*, creator_fees_token*). Ketika pemeriksaan invariant constant-product memeriksa k' ≥ k, ia menggunakan saldo vault minus ketiga biaya yang terkumpul tetapi belum diswep — sehingga LP hanya menangkap lp_fee. Lihat products/cpmm/fees untuk instruksi pengumpulan dan contoh numerik yang dikerjakan.

SwapBaseInput (input-exact)

“Pengguna memberi kami tepat amount_in dari input mint dan menerima minimal minimum_amount_out dari output mint.” Mengabaikan Token-2022 sebentar:
Menurut aljabar: amount_out=yΔxnetx+Δxnet\text{amount\_out} = \frac{y \cdot \Delta x_{\text{net}}}{x + \Delta x_{\text{net}}} di mana Δx_net = amount_in_after_trade_fee. Program kemudian memperbarui akuntansi vault sehingga porsi trade_fee yang terutang kepada protocol/fund/creator duduk di bucket “accrued” (tidak termasuk dalam x kurva berikutnya), sementara saham LP bergabung dengan x untuk swap berikutnya.

Token-2022 di sisi input

Jika input mint memiliki extension transfer-fee, mint mengurangi biayanya pada transfer dari user → vault. Jadi vault benar-benar menerima amount_in − transfer_fee_in(amount_in). Program CPMM oleh karena itu menghitung:
dan menjalankan kurva terhadap amount_in_after_trade_fee. Ini penting karena harga kurva dihitung dari jumlah bersih yang mendarat di vault, bukan dari jumlah judul pengguna.

Token-2022 di sisi output

Jika output mint memiliki transfer fee, pool mengirim amount_out dari vault-nya ke pengguna. Mint kemudian akan mengambil biayanya dalam perjalanan keluar, sehingga pengguna menerima amount_out − transfer_fee_out(amount_out). Program menghitung amount_out dari kurva seperti biasa, tetapi adalah tanggung jawab integrator untuk mengonversi angka “vault send” pool menjadi angka “user receive” saat menampilkan penawaran.

Pemeriksaan slippage

Setelah menghitung amount_out:
Jika output mint mengenakan transfer fee, SDK menerapkan transfer fee sebelum menetapkan minimum_amount_out sehingga konstanta slippage didenominasikan dalam apa yang benar-benar akan diterima pengguna, bukan dalam apa yang vault kirim.

SwapBaseOutput (output-exact)

“Pengguna akan menerima tepat amount_out dari output mint dan bersedia membayar hingga maximum_amount_in dari input mint.” Membalik kurva untuk Δx_net: Δxnet=xamount_outyamount_out\Delta x_{\text{net}} = \left\lceil \frac{x \cdot \text{amount\_out}}{y - \text{amount\_out}} \right\rceil Ceiling penting — ia menjamin k' ≥ k setelah pemotongan integer. Kemudian:
Pada Token-2022 input, bungkus dengan:
sehingga pengguna membayar cukup sehingga setelah pengurangan transfer-fee mint pool masih menerima gross_needed.

Pemeriksaan slippage

Contoh yang dikerjakan

Pool state, mengabaikan Token-2022:
  • x = 1_000_000_000_000 (1.000.000,000000 dari token0, 6 desimal)
  • y = 2_000_000_000_000 (2.000.000,000000 dari token1, 6 desimal)
  • AmmConfig: trade_fee_rate = 2500, protocol_fee_rate = 120_000, fund_fee_rate = 40_000, creator_fee_rate = 0
Pengguna: SwapBaseInput dengan amount_in = 1_000_000_000 (1.000,000000 dari token0). Creator fee dinonaktifkan (enable_creator_fee = false).
Jika pool yang sama memiliki enable_creator_fee = true dengan creator_fee_rate = 1000 (0,10%) di sisi input, program akan mengenakan total_input_fee = ceil(1_000_000_000 * 3500 / 1_000_000) = 3_500_000, kemudian membaginya sebagai creator_fee = 1_000_000 dan trade_fee = 2_500_000. Aritmetika protocol/fund/LP pada trade_fee tidak berubah dari contoh di atas — creator fee adalah bucket sendiri, terkumpul ke creator_fees_token0 dan dikecualikan dari curve_x bersama dengan bucket protocol dan fund. Jika input mint memiliki transfer fee Token-2022 1%, vault menerima 990_000_000 token alih-alih 1_000_000_000, dan setiap perhitungan berikutnya menggunakan jumlah bersih tersebut.

Aturan pembaruan observation

Pada setiap swap, program mengevaluasi apakah akan mendorong observation baru ke ring buffer:
Dua properti:
  • Harga kumulatif, bukan harga spot. Satu observation bukan harga. Untuk mendapatkan TWAP dari waktu t0 ke t1, baca observation terdekat dengan setiap ujung dan hitung (cumulative(t1) − cumulative(t0)) / (t1 − t0).
  • Sampel dibatasi kecepatan. Swap back-to-back di slot yang sama dapat berbagi satu observation. Membaca observation segera setelah swap oleh karena itu dapat terlihat usang satu slot — ini normal.
Lebih lanjut di products/clmm/accounts.

Biaya pada kurva

Ini adalah bagian yang halus dan layak diperingatkan. Aritmetika kurva bekerja terhadap saldo vault bersih — yaitu, saldo SPL mentah dikurangi biaya protocol, fund, dan creator yang terkumpul (ketiga-tiganya adalah bucket independen — lihat products/cpmm/fees). Gambaran konkret:
Konsekuensi untuk integrator:
  • Jangan quote dari saldo mentah. Kurangi bidang accrued-fee terlebih dahulu, atau panggil SwapBaseInput sebagai simulasi dan ambil hasilnya.
  • CollectProtocolFee memindahkan token keluar dari vault. Setelah pengumpulan, raw_vault_balance turun tetapi curve_balance tidak berubah; harga pool tidak bergerak. Ini disengaja.

Presisi dan overflow

  • Semua aritmetika kurva menggunakan intermediate u128 untuk mencegah overflow pada x * y.
  • Divisi dibulatkan menuju nol kecuali untuk Δx_net milik SwapBaseOutput, yang dibulatkan ke atas, dan komputasi fee, yang dibulatkan ke atas pada trade_fee dan ke bawah pada sub-split. Arah pembulatan ini dipilih sehingga invariant tidak pernah berkurang karena pemotongan integer.
  • Pool dengan rasio vault ekstrem (miliaran : 1) dapat mengalami lantai presisi pada perdagangan kecil; program mengembalikan ZeroTradingTokens dalam hal itu. Lihat reference/error-codes.

Ke mana selanjutnya

Sumber: