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

> x·y=k 不變式、基於準備金的定價、滑點推導，以及 Raydium CPMM 和 AMM v4 使用的手續費處理變體。這是每個 x·y=k 產品在 Raydium 上的參考數學頁面。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/algorithms/constant-product)
</Info>

## 不變式

常數乘積做市商（CPMM）持有兩個準備金 `x` 和 `y`，並強制執行：

```
x · y ≥ k       (每次交易後)
```

其中 `k` 是交易前準備金的乘積。對於無手續費的市場，`x · y = k` 完全相等。有手續費時，`k` 會嚴格增長（LP 手續費份額保留在準備金中）。

此不變式刻意採用幾何形式：它保證無論一個準備金變得多小，另一個都會無界增長以匹配——即池永遠不會在任一側被耗盡至零。

## 定價

### 現貨價格

任何時刻 `y` 相對於 `x` 的邊際價格是曲線的切線：

```
p = y / x
```

（推導：對 `x · y = k` 進行隱函數求導得到 `dy/dx = −y/x`；忽略符號，`|dy/dx| = y/x`）。

這是池對無限小交易報價的價格。對於任何有限交易，實際價格因沿曲線滑點而變差。

### 精確輸入交換（給定 `Δx`，收到 `Δy`）

有手續費時，設 `f` 為手續費率（例如 `f = 0.0025` 代表 25 bps）。對輸入應用手續費，然後使用不變式求解輸出：

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

交易後準備金：

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

完整的 `Δx` 進入準備金。LP 手續費份額保留在 `x'` 中；協議份額通過單獨的會計步驟從曲線中排除（見下方的[手續費會計變體](#手續費會計變體)）。

### 精確輸出交換（收到 `Δy`，支付最小 `Δx`）

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

`Δx` 向上舍入以確保池不會低估收費。

## 滑點和價格影響

**價格影響**衡量池的現貨價格因交易而移動的幅度：

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

對於小的 `Δx / x`，一階展開給出：

```
impact ≈ 2 · Δx / x      (忽略手續費)
```

直觀理解：1% 的交換會導致約 2% 的價格影響。這個 2 的係數就是為什麼 CPMM 池對中等規模交易的報價相比訂單簿市場看起來「流動性差」——你不僅在購買當前最佳出價，還在走高自己的邊際價格。

**交換者支付的有效價格**：

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

`p_before` 和 `effective` 之間的差價是**滑點**。鏈上 `slippage` UI 通常表示為 `(effective − p_before) / p_before`；SDK 的 `computeAmountOut` 因此返回 `amountOut` 和 `priceImpact`。

## 程式碼中的不變式檢查

交換後，協議會重新驗證：

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

任何違反都是程式錯誤或算術溢出。Raydium 的交換指令將此檢查明確設為後置條件：

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

## 手續費會計變體

不變式檢查假設 LP 手續費保留在準備金中。不同的 Raydium 產品以不同方式處理協議／基金／建立者分量：

### CPMM 約定

手續費是 `1_000_000` 分母上的 `u64` 基點類似率。交易手續費分為 `trade_fee_rate`（總計），然後通過 `protocol_fee_rate`、`fund_fee_rate`、`creator_fee_rate` 細分。每次交換時：

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

三個非 LP 份額累積到單獨的計數器（`protocol_fees_*`、`fund_fees_*`、`creator_fees_*`）中，這些計數器**排除在**用於不變式的準備金之外。這就是手續費可以不移動曲線的情況下掃出的方式。見 [`products/cpmm/fees`](/zh-Hant/products/cpmm/fees)。

### AMM v4 約定

手續費是 `10_000` 分母上的 `numerator / denominator` 比率。分割在池建立時固定並儲存在 `AmmInfo.fees` 上：

```
swap_fee  = ceil(Δx · swap_fee_numerator / swap_fee_denominator)    // 例如 0.25%
pnl_share = swap_fee · pnl_numerator / swap_fee_numerator            // 例如 0.03 / 0.25 = 12%
lp_share  = swap_fee − pnl_share                                     // 0.22% 的交易量
```

`pnl_share` 累積到 `state_data.need_take_pnl_*` 並從準備金中排除；`lp_share` 保留在金庫中。見 [`products/amm-v4/fees`](/zh-Hant/products/amm-v4/fees)。

兩個約定以相同方式保留不變式——差異是表面的（分母 + 子類別數量）。

## 舍入規則

* \*\*手續費計算向上舍入。\*\*確保池永遠不會低估手續費。
* \*\*輸出金額向下舍入。\*\*確保不變式嚴格成立（在添加手續費之前甚至 `k' > k`）。
* \*\*精確輸出輸入金額向上舍入。\*\*確保使用者不會少付。

所有算術都對中間 `x · Δx` 乘積使用 `u128` 以避免大準備金上的溢出。最終結果使用飽和檢查轉換回 `u64`。

## 邊界情況

### 空池

在第一個 `Deposit` 之前，`x = y = 0`。交換指令拒絕前 Deposit。

### 零輸出

如果 `Δx` 足夠小使得向下舍入的 `Δy` 為 0，指令以 `ZeroTradingTokens` 還原。這防止在沒有支付的情況下提取價值；也意味著高度不平衡池上的塵埃交換失敗。

### 塵埃 LP

第一個 `Deposit` 有特殊處理：它將初始 LP 供應計算為 `sqrt(x · y)` 並燃燒少量「初始燃燒」金額（通常 100 LP 單位）以防止「首存入充氣攻擊」（攻擊者捐贈給金庫並膨脹 LP 代幣價值）。後續存款使用按比例數學。

## 與套利的關係

CPMM 池的價格只能通過以下方式改變：

1. 通過池本身的交易（使用者沿曲線行走）。
2. 捐贈（向金庫發送代幣而不進行交換）。

因為交易以曲線確定性地移動價格，任何價格與更廣泛市場不同的池都會創造套利機會。套利者將池價格帶回預期的市場價格。這就是為什麼 CPMM 池被稱為「不需要預言機就能報價」：市場通過套利而不是池外部讀取來找到價格。

反面：池本身是套利者的交易對手，所以任何套利利潤都是 LP 無常損失（減去 LP 捕獲的手續費）。

## 已計算的範例

### 範例 1——小交易，可忽略不計的滑點

池：`x = 1_000_000, y = 2_000_000, k = 2·10^12`。手續費 `f = 0.0025`。

交易 `Δ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
```

有效價格：`1000 / 1993.01 ≈ 0.5018`。之前現貨：`0.5`。影響：約 0.36%。

### 範例 2——中等規模交易，顯著滑點

同一池，`Δx = 100_000`（`x` 的 10%）：

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

有效：`100_000 / 181_405 ≈ 0.5513`。影響：約 10.3%——大約是 `2 · 10% = 20%` 經驗法則的一半（該法則是無手續費常數乘積曲線的最壞情況上限；交易手續費加上公式中的反演將其降低）。

## 指標

* [`products/cpmm/math`](/zh-Hant/products/cpmm/math) — CPMM 的特定舍入 + 手續費分母選擇。
* [`products/amm-v4/math`](/zh-Hant/products/amm-v4/math) — AMM v4 的 OpenBook 整合準備金如何擴展此模型。
* [`algorithms/slippage-and-price-impact`](/zh-Hant/algorithms/slippage-and-price-impact) — 關於 UI 滑點容差大小調整的專用頁面。

來源：

* Uniswap v2 白皮書——`x · y = k` 的規範陳述。
* Raydium CPMM 程式原始碼。
* Raydium AMM v4 程式原始碼。
