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

# Stable AMM 数学

> ルックアップテーブルから価格を引用するための二分探索と線形補間。フィー適用は AMM v4 と同一。OpenBook 分離後の純粋 AMM プール会計。

<Info>
  **このページは AI による自動翻訳です。すべての内容は英語版を正とします。**

  [英語版を表示 →](/products/stable/math)
</Info>

## ルックアップテーブル曲線

Stable AMM は、式 x·y=k をスパースなルックアップテーブル（x、y、price のタプル）に置き換えます。スワップの価格設定時、プログラムは以下を実行します：

1. リザーブから現在のプール比率を計算します。
2. **二分探索**でテーブルを検索し、その比率をブラケットする 2 つのエントリを見つけます。
3. **線形補間**でそれらの間の中間価格を取得します。
4. フィーを適用して見積もりを返します。

このアプローチは、式の決定性を**管理者の柔軟性**と価格形成の自由度と引き換えにし、Solana のコンピュート予算に収まるほど効率的です。

## テーブルレイアウトと二分探索

`ModelDataInfo` は最大 50,000 個の `DataElement` エントリを保持し、管理者によってインデックス付けされます。最初の `valid_data_count` のみがアクティブです。各エントリ：

```
DataElement {
  x: u64,      // X 座標（コイン側の金額、スケール済み）
  y: u64,      // Y 座標（PC 側の金額、スケール済み）
  price: u64,  // price = x/y、乗数でスケール済み
}
```

現在のプールリザーブ（x\_real、y\_real）での価格を見つけるには：

1. 比率を計算します：`target_ratio = (x_real * multiplier) / y_real`。
2. `(element.x * multiplier) / element.y` が `target_ratio` をブラケットするエントリを二分探索します。
3. ブラケット `[min_idx, max_idx]` が見つかったら、補間します。

プログラムの二分探索コードは `state.rs::ModelDataInfo::get_mininum_range_by_xy_real` で約 150 行にわたります。重要な不変量：**エントリはソート済み**（x 昇順、y 降順、price 昇順）である必要があります。

## 線形補間

2 つのテーブルポイントが比率をブラケットしたら、補間は中間価格とリザーブペアを計算します：

```
target = (x_real * multiplier) / y_real

[x1, y1, p1] = table[min_idx]
[x2, y2, p2] = table[max_idx]

// 価格を補間
p = p1 + (p2 - p1) * (target - ratio1) / (ratio2 - ratio1)

// リザーブを補間
x = x1 + (x2 - x1) * (target - ratio1) / (ratio2 - ratio1)
y = y1 + (y2 - y1) * (target - ratio1) / (ratio2 - ratio1)
```

結果は、テーブルポイントをスムーズに接続する区分線形曲線です。

## スケーリング：乗数

プールリザーブと価格は異なるスケールで保存されます。`ModelDataInfo` の `multiplier` フィールドがこれを考慮します。一般的なパターン：

* コインは 6 デシマル、PC は 18 デシマル。
* 乗数 = 10^6（またはそれに類するもの）。
* テーブルエントリは u64 の境界に収まるように縮小スケールで保存されます。

プログラムは読み書き時に以下を通じてリスケールします：

```
real_value = table_value * ratio / multiplier
table_value = real_value * multiplier / ratio
```

## スワップ価格設定：`SwapBaseIn` と `SwapBaseOut`

### SwapBaseIn（正確な入力）

入力額 `amount_in` が与えられた場合：

1. `(coin_vault, pc_vault)` から現在の比率を取得します。
2. ブラケットするテーブルエントリを見つけて補間し、テーブル空間の比率を取得します。
3. 入力をテーブル空間に変換します：`dx_table = amount_in * multiplier / ratio`。
4. 新しい X 座標でテーブルをクエリして新しい Y を見つけます。
5. `dy_table = y_old - y_new`。
6. 変換し直します：`dy_real = dy_table * ratio / multiplier`。
7. トレードフィーを適用します：`dy_output = dy_real - (dy_real * trade_fee_numerator / trade_fee_denominator)`。
8. `dy_output` を返します。

### SwapBaseOut（正確な出力）

対称：目的の `amount_out` が与えられた場合、必要な `amount_in` を解きます。

両方のパスは、プールボルトから直接有効リザーブを読み取ります。プールは数年間 OpenBook オープンオーダーを保持していないため、最初に決済するものはありません。ボルト残高がすべてです。（[2026-06-22 アップグレード](/ja/reference/changelog)は残りのマーケットコードを削除しました。）

## フィー適用

AMM v4 と同一です。完全な導出については [`products/amm-v4/math`](/ja/products/amm-v4/math) を参照してください。

```
gross_fee = amount_in * (swap_fee_numerator / swap_fee_denominator)    // 例：0.25%
lp_portion = gross_fee - (gross_fee * pnl_numerator / pnl_denominator) // 例：0.22%
pnl_portion = gross_fee * (pnl_numerator / pnl_denominator)            // 例：0.03%
```

`pnl_portion` は `need_take_pnl_*` に移動し、管理者が `WithdrawPnl` で回収します。`lp_portion` はボルトに留まり、`k` を増加させ、LP トークンホルダーに利益をもたらします。

## プール資産会計

この式は、歴史的にプールが OpenBook OpenOrders アカウントにオープンオーダーとして保有していた資金を追加していました。プールが注文の投稿を停止してから実際にはゼロになっており、2026-06-22 アップグレードはこれを式から完全に削除し、ボルトのみの計算を残しました：

```
旧：total assets = vault balances + open-order funds (native_coin_total / native_pc_total) − pending PnL (need_take_pnl)
新：total assets = vault balances − pending PnL (need_take_pnl)
```

これは、曲線数学が有効リザーブとして扱う値です（蓄積されたが未回収の `need_take_pnl` 部分は物理的にボルトに存在しますが、価格設定から除外されます）。以前 OpenOrders 残高を読み取っていた見積もりコードとインデクサーはそのタームを削除する必要があります。

## MonitorStep（削除）

`MonitorStep` は、保留中の OpenBook フィルを決済し、`AmmInfo.target_orders` を再計算し、ルックアップテーブルから導出された指値注文グリッドを再投稿する**クランク命令**でした。プールは数年前に OpenBook への注文投稿を停止したため、クランクには何もすることがなくなりました。2026-06-22 アップグレードで**削除されました**。インテグレーターは Stable プールをクランクする必要はありません。

## 概要：これが機能する理由

ルックアップテーブル + 補間設計は**効率的で柔軟**です：

* **効率性：** 二分探索は O(log 50,000) ≈ 16 イテレーション、各 \~ 300–500 CU。補間は数回の乗算・除算。総見積もりコストは \~5k–15k CU で、スワップごとに式を再計算するより大幅に安価です。
* **柔軟性：** 管理者は任意の区分線形曲線をエンコードできます。ステーブルコインペアは 1:1 の周辺で高密度を取得します。担保付きペアはカスタム曲線を取得します。
* **自己完結型流動性：** すべての資金はプールボルトに存在し、価格設定はそれらを直接読み取ります。クランク、外部オーダーブック、トランザクションあたりのアカウント数が少なくなります。

補間ロジックの詳細については、`raydium-stable/program/src/state.rs` のメソッド `get_data_by_x`、`get_data_by_y`、`get_dy_by_dx_base_in` などを参照してください。

## 次のステップ

* [アカウント](/ja/products/stable/accounts) — `ModelDataInfo` と `DataElement` フィールドリファレンス。
* [命令](/ja/products/stable/instructions) — 呼び出し可能なセット（スワップ、デポジット、ウィズドロー、`WithdrawPnl`）と削除された命令。
* [フィー](/ja/products/stable/fees) — フィー適用と `WithdrawPnl`。
* [`products/amm-v4/math`](/ja/products/amm-v4/math) — OpenBook フィー包含注文価格設定ロジック用。

ソース：

* `raydium-stable/program/src/state.rs`（補間と二分探索の実装）
* `raydium-stable/program/src/math.rs`（計算機ユーティリティ）
