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

Invarian

CPMM mempertahankan invarian constant-product klasik pada dua vault-nya: x⋅y=kx \cdot y = k di mana x adalah saldo vault0 setelah biaya transfer Token-2022 pada penerimaan, dan demikian pula untuk y. Setiap swap harus meninggalkan k' ≥ k setelah memperhitungkan biaya perdagangan yang dikreditkan ke LP (bucket protokol, dana, dan kreator tidak dihitung menuju k — mereka berada 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. Harga saham LP ditentukan oleh cadangan pool, bukan oleh k: harga LP dalam token0=xlpSupply,harga LP dalam token1=ylpSupply\text{harga LP dalam token0} = \frac{x}{\text{lpSupply}}, \qquad \text{harga LP dalam token1} = \frac{y}{\text{lpSupply}} Membakar ΔLP token LP mengembalikan tepat ΔLP × x / lpSupply dari token0 dan ΔLP × y / lpSupply dari token1. Baik kurva maupun k tidak bergerak pada deposit atau penarikan — hanya swap yang mengubah harga.

Model biaya pada jalur swap

CPMM menerapkan dua biaya yang dinilai secara independen pada setiap swap:
  • Biaya perdagangan diambil di sisi input, dikenakan pada AmmConfig.trade_fee_rate. Kemudian dibagi menjadi saham LP, protokol, dan dana (saham LP tetap di vault dan menumbuhkan k; saham protokol dan dana diekstrak dari akuntansi vault).
  • Biaya kreator (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 tersendiri — tidak pernah bagian dari biaya perdagangan.
Saham protokol dari biaya kreator tidak muncul di mana pun di halaman ini, dan itu disengaja. Ini diterapkan ketika CollectCreatorFee memindahkan biaya yang terkumpul antara dua penghitung yang kurva sudah kecualikan — bukan selama swap. Matematika swap, kutipan, dan k identik dengan dan tanpa itu. Lihat products/cpmm/fees.
Misalkan:
  • FEE_RATE_DENOMINATOR = 1_000_000
  • trade_fee_rate — dari AmmConfig, misalnya 2500 = 0,25% dari sisi volume yang relevan
  • creator_fee_rate — dari AmmConfig, misalnya 1000 = 0,10% dari sisi volume yang relevan
  • protocol_fee_rate, fund_fee_rate — dinyatakan dalam satuan 1/FEE_RATE_DENOMINATOR dari biaya perdagangan, bukan dari volume
Ketika biaya kreator berada di sisi input:
Ketika biaya kreator berada di sisi output:
Dalam kedua kasus, biaya perdagangan dibagi dengan cara yang sama:
Jumlah protocol_fee + fund_fee + creator_fee disimpan di vault tetapi dilacak secara terpisah pada status pool (protocol_fees_token*, fund_fees_token*, creator_fees_token*). Ketika pemeriksaan invarian constant-product k' ≥ k, ia menggunakan saldo vault minus ketiga biaya yang terkumpul tetapi belum disapu — jadi 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 mint input dan menerima setidaknya minimum_amount_out dari mint output.” Mengabaikan Token-2022 untuk saat ini:
Dengan 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 bagian dari trade_fee yang dihutangkan kepada protokol/dana/kreator duduk di bucket “terkumpul” (tidak termasuk dalam x kurva berikutnya), sementara saham LP bergabung dengan x untuk swap berikutnya.

Token-2022 di sisi input

Jika mint input memiliki ekstensi transfer-fee, mint mengurangi biayanya pada transfer dari pengguna → vault. Jadi vault sebenarnya 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 headline pengguna.

Token-2022 di sisi output

Jika mint output memiliki biaya transfer, pool mengirim amount_out dari vault-nya ke pengguna. Mint kemudian akan mengambil biayanya dalam perjalanan keluar, jadi pengguna menerima amount_out − transfer_fee_out(amount_out). Program menghitung amount_out dari kurva seperti biasa, tetapi tanggung jawab integrator untuk mengonversi nomor “pengiriman vault” pool menjadi nomor “penerimaan pengguna” saat menampilkan kutipan.

Pemeriksaan slippage

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

SwapBaseOutput (output-exact)

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

Pemeriksaan slippage

Contoh yang dikerjakan

Status pool, 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). Biaya kreator 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 protokol/dana/LP pada trade_fee tidak berubah dari contoh di atas — biaya kreator adalah bucket tersendiri, terkumpul ke creator_fees_token0 dan dikecualikan dari curve_x bersama dengan bucket protokol dan dana. Jika mint input memiliki biaya transfer Token-2022 1%, vault menerima 990_000_000 token alih-alih 1_000_000_000, dan setiap perhitungan berikutnya menggunakan jumlah bersih itu.

Aturan pembaruan observasi

Pada setiap swap, program mengevaluasi apakah akan mendorong observasi baru ke dalam ring buffer:
Dua properti:
  • Harga kumulatif, bukan harga spot. Satu observasi bukan harga. Untuk mendapatkan TWAP dari waktu t0 ke t1, baca observasi terdekat dengan setiap ujung dan hitung (cumulative(t1) − cumulative(t0)) / (t1 − t0).
  • Sampel dibatasi laju. Swap berturut-turut dalam slot yang sama dapat berbagi satu observasi. Membaca observasi 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 patut disoroti. Aritmetika kurva bekerja terhadap saldo vault bersih — yaitu, saldo SPL mentah minus biaya protokol, dana, dan kreator yang terkumpul (ketiga-tiganya adalah bucket independen — lihat products/cpmm/fees). Gambaran konkret:
Konsekuensi untuk integrator:
  • Jangan kutip dari saldo mentah. Kurangi bidang biaya terkumpul 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 perantara u128 untuk mencegah overflow pada x * y.
  • Pembagian dibulatkan menuju nol kecuali untuk Δx_net SwapBaseOutput, yang dibulatkan ke atas, dan perhitungan biaya, yang dibulatkan ke atas pada trade_fee dan ke bawah pada sub-split. Arah pembulatan ini dipilih sehingga invarian tidak pernah berkurang karena pemotongan integer.
  • Pool dengan rasio vault ekstrem (miliaran : 1) dapat mencapai lantai presisi pada perdagangan kecil; program mengembalikan ZeroTradingTokens dalam hal itu. Lihat reference/error-codes.

Ke mana selanjutnya

Sumber: