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

# رسوم CPMM

> كيف يفرض CPMM رسم تداول ورسم منشئ منفصل، ويقسم رسم التداول بين مزودي السيولة وخزينة البروتوكول وصندوق multisig، ومن يجمع ماذا وأين.

<Info>
  **هذه الصفحة مُترجَمة آليًا بواسطة الذكاء الاصطناعي. النسخة الإنجليزية هي المرجع المعتمد.**

  [عرض النسخة الإنجليزية →](/products/cpmm/fees)
</Info>

## رسمان مستقلان، أربع وجهات

يفرض CPMM **رسمين بمعدلات منفصلة** على كل مبادلة:

1. **رسم التداول** — يُحتسب بـ `AmmConfig.trade_fee_rate` وينقسم إلى ثلاث وجهات:
   * **حصة مزود السيولة (LP)** — تبقى في الخزينة وتزيد `k`. يتم المطالبة بها ضمنيًا بحرق رموز LP.
   * **حصة البروتوكول** — تُستحق على `PoolState.protocol_fees_token*`؛ يتم جمعها بواسطة `protocol_owner` عبر `CollectProtocolFee`.
   * **حصة الصندوق** — تُستحق على `PoolState.fund_fees_token*`؛ يتم جمعها بواسطة `fund_owner` عبر `CollectFundFee`.
2. **رسم المنشئ** (اختياري، لكل pool) — يُحتسب بـ `AmmConfig.creator_fee_rate` **بشكل مستقل** عن رسم التداول، يُستحق على `PoolState.creator_fees_token*`، يتم جمعه بواسطة `pool_state.pool_creator` عبر `CollectCreatorFee`. يكون نشطًا فقط عندما تم إنشاء pool باستخدام `enable_creator_fee = true`.

رسم المنشئ **ليس** جزءًا من رسم التداول. يتم إضافة المعدلين معًا عند حساب الرسم على مدخل التبادل، لكن كل واحد منهما يبقى في سلة خاصة به — حصص البروتوكول والصندوق تُشتق دائمًا من `trade_fee` فقط، لا من `creator_fee`. يفرض pool بـ `creator_fee_rate = 1000` (0.10%) و `trade_fee_rate = 2500` (0.25%) رسمًا مجمعًا بنسبة 0.35% من المدخل على مبادلة "creator-fee-on-input"، منها يحتفظ المنشئ بـ 0.10% وتحصل سلة رسم التداول على 0.25%.

معدلات رسم التداول (`trade_fee_rate`, `protocol_fee_rate`, `fund_fee_rate`) و `creator_fee_rate` موجودة جميعها على `AmmConfig`. العلم لكل pool `enable_creator_fee` وموضع `creator_fee_on` (أي جانب من التداول يتم أخذ رسم المنشئ منه) موجودان على `PoolState`. انظر [`products/cpmm/accounts`](/ar/products/cpmm/accounts).

## المعدلات والوحدات

جميع المعدلات `u64`s موصوفة بوحدات `1 / FEE_RATE_DENOMINATOR` حيث `FEE_RATE_DENOMINATOR = 1_000_000`.

* **`trade_fee_rate`** هو جزء من **حجم المبادلة**. `2500` ⇒ 0.25% من الجانب ذي الصلة (مدخل أو مخرج، حسب `creator_fee_on` — انظر "أي جانب من التداول يتم أخذ الرسوم منه" أدناه).
* **`creator_fee_rate`** هو جزء من **حجم المبادلة**، يتم أخذه **بشكل منفصل** عن رسم التداول. `1000` ⇒ 0.10% من الجانب ذي الصلة.
* **`protocol_fee_rate`** و **`fund_fee_rate`** هما نسبتان من **رسم التداول**، وليس من الحجم. `120_000` ⇒ 12% من رسم التداول.

معاملات افتراضية لـ `AmmConfig[index=0]` (pool "المعياري" 0.25%) على mainnet، للمرجعية:

| الحقل               | القيمة        | النسبة المئوية الفعلية                   |
| ------------------- | ------------- | ---------------------------------------- |
| `trade_fee_rate`    | `2500`        | 0.25% من الحجم (سلة رسم التداول)         |
| `protocol_fee_rate` | `120000`      | 12% من رسم التداول ≈ **0.030% من الحجم** |
| `fund_fee_rate`     | `40000`       | 4% من رسم التداول ≈ **0.010% من الحجم**  |
| `creator_fee_rate`  | `0` (افتراضي) | 0% (سلة منفصلة)                          |
| → حصة LP الفعلية    |               | **0.210% من الحجم**                      |

لذا على مبادلة بقيمة \$1,000 مقابل `AmmConfig[0]` مع `enable_creator_fee = false`: \$2.50 إجمالي رسم التداول، منها \$2.10 تبقى مع مزودي السيولة، \$0.30 تذهب للبروتوكول، \$0.10 للصندوق. سلة المنشئ هي 0 لأن رسم المنشئ معطّل.

إذا كان نفس pool به `enable_creator_fee = true` و `creator_fee_rate = 1000` (0.10%)، يدفع المستخدم إضافي \$1.00 لسلة المنشئ — يتم أخذه من نفس جانب التداول المُعدّ بواسطة `creator_fee_on` — لإجمالي \$3.50 من الرسوم. سلة رسم التداول وانقساماتها بين البروتوكول والصندوق تبقى دون تغيير.

تأكد من القيم الحالية على mainnet مقابل `GET https://api-v3.raydium.io/main/cpmm-config` — المعدلات قابلة للتغيير من قبل المسؤول وينبغي قراءتها بشكل طازج بدلاً من برمجتها.

## الانقسام، في الكود

```rust theme={null}
// معاد صياغة من raydium-cp-swap/programs/cp-swap/src/curve/{calculator,fees}.rs.
// الكود الفعلي يتفرع على `is_creator_fee_on_input`؛ كلا الفرعين يحافظان على
// الثابت أن creator_fee هو معدله الخاص، وليس أبدًا جزءًا من trade_fee.

const FEE_RATE_DENOMINATOR_VALUE: u64 = 1_000_000;

pub struct FeeBreakdown {
    pub amount_in_after_fees: u64,    // المدخل بعد خصم جميع الرسوم من جانب المدخل
    pub amount_out_after_fees: u64,   // المخرج بعد طرح أي رسم منشئ من جانب المخرج
    pub trade_fee:    u64,            // → ينقسم إلى سلات LP / بروتوكول / صندوق أدناه
    pub protocol_fee: u64,            // حصة من trade_fee
    pub fund_fee:     u64,            // حصة من trade_fee
    pub creator_fee:  u64,            // سلة مستقلة (جانب المدخل أو المخرج)
}

fn take_fees_on_input(
    amount_in: u64,
    trade_rate: u64,
    creator_rate: u64,
    protocol_rate: u64,
    fund_rate: u64,
) -> (u64 /* trade_fee */, u64 /* creator_fee */, u64 /* amount_in_after_fees */) {
    // يتم إضافة المعدلين لذا نقرب مرة واحدة على الرسم المجمع، ثم ننقسم
    // بناءً على التناسب — هذا مجرد خدعة تقريب/كفاءة. الانقسام
    // يحترم المعدلات بدقة: creator_fee/trade_fee == creator_rate/trade_rate.
    let total_fee = ((amount_in as u128) * ((trade_rate + creator_rate) as u128))
        .div_ceil(FEE_RATE_DENOMINATOR_VALUE as u128) as u64;

    let creator_fee = ((total_fee as u128) * (creator_rate as u128)
                       / ((trade_rate + creator_rate) as u128)) as u64;
    let trade_fee   = total_fee - creator_fee;

    (trade_fee, creator_fee, amount_in - total_fee)
}

fn take_creator_fee_on_output(amount_out_swapped: u64, creator_rate: u64) -> (u64, u64) {
    // عندما يوجه creator_fee_on رسم المنشئ إلى جانب المخرج،
    // يتم أخذ trade_fee من المدخل كمعدل واحد، و creator_fee
    // يُحسب ضد مخرج المنحنى.
    let creator_fee = ((amount_out_swapped as u128) * (creator_rate as u128))
        .div_ceil(FEE_RATE_DENOMINATOR_VALUE as u128) as u64;
    (amount_out_swapped - creator_fee, creator_fee)
}

fn split_trade_fee(
    trade_fee: u64,
    protocol_rate: u64,
    fund_rate: u64,
) -> (u64 /* protocol_fee */, u64 /* fund_fee */) {
    let protocol_fee = (trade_fee as u128 * protocol_rate as u128
                        / FEE_RATE_DENOMINATOR_VALUE as u128) as u64;
    let fund_fee     = (trade_fee as u128 * fund_rate as u128
                        / FEE_RATE_DENOMINATOR_VALUE as u128) as u64;
    (protocol_fee, fund_fee)
}
```

ملاحظات:

* إجمالي الرسم على المدخل يقرّب **لأعلى** بحيث لا يقل البروتوكول أبدًا.
* الانقسامات الفرعية لـ `trade_fee` (بروتوكول، صندوق) تقرّب **لأسفل** بحيث لا يتجاوز مجموعهما `trade_fee`؛ البقية هي حصة LP.
* `lp_share = trade_fee − protocol_fee − fund_fee` (creator\_fee **لا** يُطرح هنا لأنه سلة خاصة به).
* يتم أخذ رسم المنشئ من المدخل أو المخرج حسب `PoolState.creator_fee_on` (انظر القسم التالي). المعدل لا يتغير في كلا الحالتين.

## أي جانب من التداول يتم أخذ الرسوم منه

يحتوي CPMM على إعداد لكل pool يسمى `creator_fee_on` (`BothToken` / `OnlyToken0` / `OnlyToken1`) يحدد ما إذا كان رسم المنشئ يتم أخذه من جانب **المدخل** أو جانب **المخرج** من مبادلة معينة. دالة المساعد في وقت التشغيل `is_creator_fee_on_input(direction)` تختصرها إلى قيمة منطقية لكل مبادلة:

| `creator_fee_on`   | مبادلة `0 → 1` | مبادلة `1 → 0` |
| ------------------ | -------------- | -------------- |
| `BothToken` (`0`)  | جانب المدخل    | جانب المدخل    |
| `OnlyToken0` (`1`) | جانب المدخل    | جانب المخرج    |
| `OnlyToken1` (`2`) | جانب المخرج    | جانب المدخل    |

عندما يكون رسم المنشئ على جانب **المدخل**، يتم خصم رسم التداول ورسم المنشئ معًا من `amount_in` قبل تشغيل المنحنى. رياضيات الاقتباس: أزل `trade_rate + creator_rate` من المدخل.

عندما يكون رسم المنشئ على جانب **المخرج**، يتم خصم رسم التداول فقط من `amount_in`؛ ينتج المنحنى مخرجًا بدون رسم، ثم يتم خصم رسم المنشئ من هذا المخرج. رياضيات الاقتباس: أزل `trade_rate` من المدخل؛ أزل `creator_rate` من المخرج.

رسم التداول نفسه يتم أخذه دائمًا من جانب المدخل (نمط Uniswap-V2 المعياري). فقط رسم المنشئ يمكن أن ينتقل إلى المخرج.

## كيف تتفاعل رسوم "المستحقة" مع المنحنى

دقة مهمة: **رسوم البروتوكول والصندوق والمنشئ تبقى فيزيائيًا في الخزينة** حتى يتم استدعاء تعليمة `Collect*` الخاصة بها. لكن يتم استبعادها من رؤية المنحنى لرصيد الخزينة.

صورة ملموسة بعد مبادلة واحدة:

```
raw_vault_0_balance = getTokenAccountBalance(vault_0).amount
                    = lp_entitled + protocol_fees_token0
                      + fund_fees_token0 + creator_fees_token0

curve_x = raw_vault_0_balance − (protocol_fees_token0
                                  + fund_fees_token0
                                  + creator_fees_token0)
```

يستخدم البرنامج `curve_x` (والمثيل المماثل `curve_y`) عند فرض `k' ≥ k`. هذه هي الطريقة التي تصل بها رسوم غير LP إلى وجهاتها **بدون** تضخيم حصة LP من البركة.

العواقب التي يجب أن تصمم حولها:

* **الاقتباس من الأرصدة الخام خطأ.** إذا بنيت quoter على `getTokenAccountBalance`، ستبالغ باستمرار في سعر البركة. اطرح دائمًا الرسوم المستحقة، أو محاكي عبر `SwapBaseInput` / الـ API.
* **`CollectProtocolFee` لا يحرك السعر.** ينقل الرموز خارج الخزينة **و** يصفر عدادات `protocol_fees_token*`، لذا `curve_x` و `curve_y` لم تتغير.
* **رسوم LP لا تستحق على عداد.** إنها ضمنية في رصيد الخزينة. استحقاق LP للرسوم LP المتراكمة يتم ممارسته بحرق رموز LP (أي عبر `Withdraw`) — لا يوجد `CollectLpFee`.

## التفاعل مع رسوم نقل Token-2022

يتم تطبيق رسوم نقل Token-2022 من قبل **الرموز**، وليس من قبل CPMM. تعمل على كل نقل رموز — مبادلة، إيداع، سحب، وعمليات جمع `Collect*`. يتم حساب رياضيات رسم التداول في CPMM مقابل المبلغ الذي **وصل فعلاً إلى الخزينة**، أي بعد خصم رسم نقل مدخل الرموز (إن وجد).

لذا في أسوأ الحالات يدفع المستخدم ثلاث ضرائب متميزة على مبادلة input-exact:

1. رسم نقل مدخل الرموز على `amount_in` (لسلطة رسوم الرموز).
2. `trade_fee` البركة على البقية (مقسم كما هو أعلاه).
3. رسم نقل مخرج الرموز على `amount_out` (لسلطة رسوم الرموز).

يحسب quoter في SDK جميع الثلاثة لذا `minimum_amount_out` موصوف بما يستقبله المستخدم فعلاً. إذا كنت تكتب quoter خاص بك، اعكس هذا السلوك، أو ستكون عمليات فحص الانزلاق لديك متساهلة بشكل منهجي.

انظر [`algorithms/token-2022-transfer-fees`](/ar/algorithms/token-2022-transfer-fees) للاشتقاق التفصيلي.

## رسم المنشئ

رسم المنشئ اختياري ولكل pool. **المعدل** موجود على `AmmConfig.creator_fee_rate`؛ **العلم التفعيل** و **الجانب** (`creator_fee_on`) موجودان على `PoolState`:

* **تفعيل عند إنشاء البركة.** `Initialize` يعيّن `enable_creator_fee = false` افتراضيًا؛ يمكن للبرك المنشأة عبر `InitializeWithPermission` (المستخدمة بواسطة تخرجات LaunchLab والطرق المحمية الأخرى) أن تمرر `enable_creator_fee = true` واختيار `creator_fee_on`.
* **المعدل مشترك مع طبقة الرسم.** المعدل نفسه هو `AmmConfig.creator_fee_rate`، نفس القيمة عبر كل بركة مرتبطة بهذا التكوين. يقرر كل pool بعد ذلك ما إذا كان سيفرضه (`enable_creator_fee`) وأي جانب من المبادلة سيفرضه عليه (`creator_fee_on`). عندما `enable_creator_fee = false`، معدل رسم المنشئ الفعلي للبركة هو صفر بغض النظر عن قيمة التكوين (انظر `PoolState::adjust_creator_fee_rate` في المصدر).
* **مستقل عن رسم التداول.** رسم المنشئ لا يقلل أبدًا من حصص LP / البروتوكول / الصندوق — إنه معدله الخاص، يُطبق بشكل منفصل، يُستحق في عدادات خاصة به.
* **يتم جمعه عبر `CollectCreatorFee`**، موقّع من قبل `PoolState.pool_creator`.
* **لا يمكن إعادة تفعيله أو إعادة توجيهه بعد الإنشاء.** بركة مهيأة مع `enable_creator_fee = false` لن تفرض أبدًا رسم منشئ؛ واحدة مهيأة مع `creator_fee_on` معين لا يمكنها تبديل الجوانب.

رسوم المنشئ هي الآلية وراء نمط Raydium "Burn & Earn": يتم قفل رموز LP تحت برنامج [LP Lock](/ar/reference/program-addresses) بحيث لا يمكن للمنشئ سحب السيولة، لكن يمكنه المطالبة بـ `CollectCreatorFee` إلى الأبد.

## تدفق جمع العمليات

| الموقّع                     | التعليمة             | عدادات المصدر المصفرة      | الوتيرة المعتادة    |
| --------------------------- | -------------------- | -------------------------- | ------------------- |
| `amm_config.protocol_owner` | `CollectProtocolFee` | `protocol_fees_token{0,1}` | أسبوعيًا أو برمجيًا |
| `amm_config.fund_owner`     | `CollectFundFee`     | `fund_fees_token{0,1}`     | أسبوعيًا أو برمجيًا |
| `pool_state.pool_creator`   | `CollectCreatorFee`  | `creator_fees_token{0,1}`  | في أي وقت           |

مالكو البروتوكول والصندوق هم مجموعة Raydium متعددة التوقيع على mainnet؛ انظر [`security/admin-and-multisig`](/ar/security/admin-and-multisig). الموقّع المنشئ هو الحساب الذي شغّل `Initialize`.

## تغيير طبقة رسم

يمكن تغيير معدلات الرسوم من قبل المسؤول عبر `UpdateAmmConfig` (انظر [`products/cpmm/instructions`](/ar/products/cpmm/instructions)). تدخل التغييرات حيز التنفيذ على **المبادلة التالية** لكل بركة مرتبطة بـ `AmmConfig` — لا توجد هجرة، لأن البرك تحمل التكوين في كل مبادلة.

ما لا يستطيع المسؤول فعله:

* نقل بركة من `AmmConfig` إلى آخر.
* إعادة تسعير الرسوم المستحقة بأثر رجعي.
* جمع الرسوم بدون موقّع `protocol_owner` / `fund_owner`.

## قراءة الرسوم من بركة تعمل

```ts theme={null}
// خارج السلسلة: الرسوم المستحقة الحالية في كل سلة
const pool = await connection.getAccountInfo(poolStatePda);
const decoded = PoolState.decode(pool.data);
console.log(
  "Protocol accrued:",
  decoded.protocolFeesToken0.toString(),
  decoded.protocolFeesToken1.toString(),
);
console.log(
  "Fund accrued:",
  decoded.fundFeesToken0.toString(),
  decoded.fundFeesToken1.toString(),
);
console.log(
  "Creator accrued:",
  decoded.creatorFeesToken0.toString(),
  decoded.creatorFeesToken1.toString(),
);

// خارج السلسلة: المعدلات الفعلية اليوم.
// trade_fee_rate, creator_fee_rate هما نسب من الحجم (مقسوم 1e6).
// protocol_fee_rate, fund_fee_rate هما نسب من *رسم التداول* (نفس المقسوم).
const config = await fetch("https://api-v3.raydium.io/main/cpmm-config")
  .then((r) => r.json());
const tier = config.data.find((t) => t.index === decoded.ammConfigIndex);

const tradeFeeOfVolume   = tier.tradeFeeRate / 1_000_000;
const protocolOfTradeFee = tier.protocolFeeRate / 1_000_000;
const fundOfTradeFee     = tier.fundFeeRate / 1_000_000;
const lpOfTradeFee       = 1 - protocolOfTradeFee - fundOfTradeFee;

console.log("LP fee effective:",       (tradeFeeOfVolume * lpOfTradeFee * 100).toFixed(4), "%");
console.log("Protocol fee effective:", (tradeFeeOfVolume * protocolOfTradeFee * 100).toFixed(4), "%");
console.log("Fund fee effective:",     (tradeFeeOfVolume * fundOfTradeFee * 100).toFixed(4), "%");
console.log(
  "Creator fee effective:",
  decoded.enableCreatorFee
    ? ((tier.creatorFeeRate / 1_000_000) * 100).toFixed(4) + " %"
    : "0 % (disabled on this pool)",
);
```

## مقارنة مع CLMM و AMM v4

انظر [`reference/fee-comparison`](/ar/reference/fee-comparison) للحصول على مصفوفة جنبًا إلى جنب. الملخص:

* **AMM v4** يستخدم رسم تداول ثابت بنسبة 0.25% مع انقسام LP/بروتوكول مختلف وبدون رسم صندوق.
* رسوم **CLMM** هي لكل طبقة spacing علامة، مستحقة لكل موضع (وليس لكل بركة)، ويتم المطالبة بها عبر `DecreaseLiquidity` أو `CollectFees`.

## إلى أين بعد ذلك

* [`products/cpmm/math`](/ar/products/cpmm/math) — حيث ينطبق خصم رسم التداول على المنحنى.
* [`products/cpmm/instructions`](/ar/products/cpmm/instructions) — قوائم حسابات تعليمة `Collect*`.
* [`algorithms/token-2022-transfer-fees`](/ar/algorithms/token-2022-transfer-fees) — كيفية دمج رسم تداول البركة مع رسم نقل الرموز بشكل صحيح.

المصادر:

* [`raydium-io/raydium-cp-swap` — `states/config.rs`, `states/pool.rs`, `states/curve.rs`](https://github.com/raydium-io/raydium-cp-swap)
* [Raydium API — `GET /main/cpmm-config`](https://api-v3.raydium.io/main/cpmm-config)
