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

# رسوم تحويل Token-2022 في المبادلات

> كيف تغير امتداد transfer-fee في Token-2022 محاسبة المبلغ قبل/بعد المبادلة، وأي منتجات Raydium تدعمها، وحالات الحدود التي يجب على المدمجين التعامل معها (الرسوم غير المتماثلة، تحديثات الرسوم، حدود الرسوم القصوى، امتدادات عدم القابلية للنقل).

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

  [عرض النسخة الإنجليزية →](/algorithms/token-2022-transfer-fees)
</Info>

<Info>
  مصفوفة الدعم: **CPMM** يدعم Token-2022 بالكامل، بما في ذلك الرموز ذات رسوم النقل. **CLMM** يدعم Token-2022 مع رسوم النقل عبر حسابات `SwapV2` الصريحة. **AMM v4** لا يدعم Token-2022 على الإطلاق. **LaunchLab** لا يدعم Token-2022 لرمز الأساس (ينشئ رموز SPL الكلاسيكية). **Farm v6** يدعم Token-2022 على كل من رموز الرهن والمكافأة.
</Info>

## ما هي رسوم النقل

Token-2022 هو برنامج SPL Token الثاني (`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` → `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`). من بين امتداداته، فإن امتداد **transfer-fee** يحتسب رسما من كل `TransferChecked` على رمز mint. تذهب الرسوم إلى مستقبل محدد من قبل سلطة mint ويمكن تحديثها من قبل السلطة (ضمن حدود معينة).

لدى mint مع رسوم النقل معاملتان ذات صلة:

* **`transfer_fee_basis_points`** — المعدل (على سبيل المثال، 100 = 1%).
* **`maximum_fee`** — حد أقصى مطلق لكل نقل (بحيث لا يدفع الأشخاص الذين يملكون مبالغ ضخمة رسوما لا حد لها).

يمكن لـ mint أن يكون لديه **اثنتان** من تكوينات رسوم النقل النشطة في نفس الوقت: الأحدث منهما (سارية الآن) والأقدم (في طريقها للإلغاء). هذا هو تصميم "الانتقال بين الحقب" — تدخل تغييرات رسوم النقل حيز التنفيذ عبر حدود الحقبة لتجنب مفاجأة المعاملات الجارية.

## لماذا هذا مهم للمبادلات

تحتفظ أوعية المجموعة برصيد فعلي. عندما يستدعي المستخدم مبادلة Raydium:

1. يرسل المستخدم `amount_in` إلى وعاء المجموعة. إذا كان **in-mint** يحتوي على رسوم نقل، فإن الوعاء يستقبل `amount_in − fee_in`، وليس `amount_in`.
2. تعمل رياضيات المبادلة على المبلغ الذي تلقته الوعاء.
3. تُرسل المجموعة `amount_out` إلى ATA المستخدم. إذا كان **out-mint** يحتوي على رسوم نقل، فإن المستخدم يستقبل `amount_out − fee_out`، وليس `amount_out`.

إذا كان برنامج المبادلة ساذجا ويستخدم المعامل `amount_in` الخام، فإن فحص الثابتة يفشل لأن الوعاء حصل على أقل من ما يعتقده البرنامج. وبالعكس، إذا حسب `amount_out` دون طرح رسوم النقل الصادرة، فسيرى المستخدم نقصانا ويلوم البرنامج.

يتعامل Raydium CPMM و CLMM (عبر `SwapV2`) مع هذا من خلال:

* **قبل المبادلة**: حساب `in_after_fee = amount_in − transfer_fee_on(amount_in, in_mint)`، واستخدام `in_after_fee` في رياضيات المنحنى.
* **بعد المبادلة**: حساب `out_gross = amount_out_from_curve`، وإرسال `out_gross` إلى المستخدم عبر `TransferChecked` والذي سيقلله برنامج Token-2022 نفسه برسوم النقل.

تُفحص حد الانزلاق `minAmountOut` للمستخدم مقابل `out_gross` (ما تُرسله المجموعة)، **وليس** مقابل ما يستقبله المستخدم. هذا كيف تتعامل كل منصة صرافة رئيسية على Solana مع Token-2022، وهذا مهم لأن:

* إذا فحصت المجموعة بعد الرسوم، فإن تحديث الرسوم بين الاقتباس والتنفيذ سيتسبب في عكس التجارة.
* فحص الرسوم المسبقة يضع الفشل على جودة الاقتباس نفسه، وليس على تغييرات الرسوم خارج النطاق للمستخدم.

يجب على واجهات المستخدم طرح رسوم نقل Token-2022 المتوقعة عند عرض "سوف تستقبل" للمستخدم.

## حساب رسوم Token-2022

يكشف برنامج SPL Token-2022 عن مساعد حتمي. في Rust:

```rust theme={null}
use spl_token_2022::extension::transfer_fee::TransferFeeConfig;
use spl_token_2022::extension::StateWithExtensions;

let mint_data = ...;
let state = StateWithExtensions::<Mint>::unpack(&mint_data)?;
let config = state.get_extension::<TransferFeeConfig>()?;

let epoch = Clock::get()?.epoch;
let fee_bp = config.get_epoch_fee(epoch).transfer_fee_basis_points;
let max_fee = u64::from(config.get_epoch_fee(epoch).maximum_fee);

let fee = (amount as u128 * fee_bp as u128 / 10_000).min(max_fee as u128) as u64;
```

في TypeScript (عبر `@solana/spl-token`):

```ts theme={null}
import { getTransferFeeConfig, getTransferFeeAmount } from "@solana/spl-token";

const config = getTransferFeeConfig(mintAccount);
const currentEpochFee = config.olderTransferFee.epoch <= currentEpoch
  ? config.newerTransferFee
  : config.olderTransferFee;

const rate   = currentEpochFee.transferFeeBasisPoints;
const maxFee = currentEpochFee.maximumFee;
const fee    = Math.min(Math.floor(amount * rate / 10_000), Number(maxFee));
```

## صيغ المبادلة المعدلة (CPMM، المدخل الدقيق)

دع `f_pool` يكون معدل رسوم المجموعة، `f_in` معدل رسوم النقل في mint، `max_in` حده الأقصى، `f_out` معدل رسوم النقل خارج mint، `max_out` حده الأقصى.

```
transfer_fee_in  = min(amount_in · f_in / 10_000, max_in)
vault_received   = amount_in − transfer_fee_in

pool_fee         = ceil(vault_received · f_pool / 1_000_000)
amount_after     = vault_received − pool_fee
amount_out_gross = y · amount_after / (x + amount_after)

transfer_fee_out = min(amount_out_gross · f_out / 10_000, max_out)
user_receives    = amount_out_gross − transfer_fee_out
```

فحص الانزلاق: `amount_out_gross ≥ min_amount_out` (وليس `user_receives ≥ min_amount_out`). يتم تعيين `minAmountOut` للمستخدم بواسطة SDK إلى `expected_gross · (1 − slippage)` — احتفظ بالحد على جانب "المُرسل"، وليس على جانب "المستقبل".

## الصيغ المعدلة (CPMM، المخرج الدقيق)

يقوم SDK بالتكرار لإيجاد `amount_in` بحيث `user_receives = amount_out_exact`:

```
# المستخدم يريد استقبال amount_out_exact بعد رسوم النقل
amount_out_gross = amount_out_exact + transfer_fee_out_for(amount_out_exact)

# ثم حل CPMM exact-output لـ amount_after:
amount_after     = ceil(x · amount_out_gross / (y − amount_out_gross))

# ثم أضف رسوم المجموعة:
vault_received   = ceil(amount_after · 1_000_000 / (1_000_000 − f_pool))

# ثم أضف رسوم النقل الداخلة:
amount_in = ceil(vault_received · 10_000 / (10_000 − f_in))
# (أو تكرار — انظر حالة حد الرسوم أدناه)
```

تجعل حدود `max_in` / `max_out` الحساب غير خطي لأنه بمجرد تفعيل الحد الأقصى، تتوقف الرسوم عن النمو. يتعامل `computeAmountIn` / `computeAmountOut` في SDK مع هذا بالتكرار إذا كانت الصيغة الساذجة ستدفع النقل فوق الحد الأقصى.

## حالات الحدود

### الرسوم غير المتماثلة (جانب واحد له رسوم، الآخر لا)

شائع في الممارسة. الصيغ أعلاه تتعامل مع هذا بالفعل — إذا كان أحد الجانبين `f_in = 0`، فإن الشروط ذات الصلة تنهار. لا توجد حالة خاصة في البرنامج.

### تحديثات الرسوم أثناء المبادلة

إذا تغيرت رسوم نقل mint بين وقت الاقتباس ووقت التنفيذ، فستكون المبادلة إما تنزل برسوم اقتصاد أسوأ قليلاً (يتحمل المستخدم الفرق ضمن تسامح الانزلاق) أو ستنعكس (ينخفض الناتج الإجمالي دون `minAmountOut`). حدود الانزلاق تمتص هذا؛ لا حماية إضافية مطلوبة.

### حد الرسوم القصوى

بمجرد أن تكون التجارة كبيرة بما يكفي للوصول إلى `maximum_fee`، فإن الرسوم تصل إلى التشبع ومزيد من النمو يكون صفرا. هذا يجعل المعدل الفعلي غير متناسب إلى الصفر للتجارات الكبيرة جداً، مما قد يسبب منحنيات أسعار غريبة على الأسواق غير السائلة بشكل عميق. يأخذ `computeAmountOut` في SDK في الاعتبار هذا.

### امتداد عدم القابلية للنقل

تستخدم بعض رموز Token-2022 امتداد `NonTransferable`، الذي يرفض جميع استدعاءات `Transfer` باستثناء إلى وتحت سلطة mint. **لا يمكن** استخدام هذه الرموز في مجموعة Raydium على الإطلاق. `CreatePool` يرفضها عند الإنشاء.

### رموز محمل الفائدة

يدعم Token-2022 أيضا امتداد `InterestBearingConfig` الذي يجعل الأرصدة تنمو بمرور الوقت. تقرأ مجموعات Raydium أرصدة الوعاء الخام (التي تتجاهل استحقاق الفائدة)، لذا على مجموعة برمز محمل الفائدة، يلتقط LPs الفائدة المستحقة كهدية خالصة كلما استردوا (نما رصيد الوعاء أسرع من تمثيل إمداد LP). يجب على المدمجين معاملة هذا كمشكلة غير ذات صلة لكن توثيقها لجانب LP.

### خطاطيف النقل

يسمح امتداد `TransferHook` في Token-2022 بـ CPI تعسفي على كل نقل. تدعم CPMM من Raydium هذه — يعيد تعليم الحسابات المتعلقة بالخطاف — لكن إضافة عادية CU وتتطلب أن يتصرف الخطاف بشكل حسن. يدعم `SwapV2` من CLMM أيضا الخطاطيف. لا يدعم AMM v4 Token-2022 على الإطلاق، لذا السؤال لا ينشأ.

## مثال عملي

مجموعة CPMM، `x = 1_000_000 USDY، y = 1_000_000 USDC`، رسوم مجموعة 0.25%.

* USDY له رسوم نقل بنسبة 1%، `max_fee = 10_000` (0.01 USDY مع 6 منازل عشرية).
* USDC لا يحتوي على رسوم نقل.

يقوم المستخدم بمبادلة `amount_in = 1_000 USDY` مقابل USDC (مدخل دقيق).

```
transfer_fee_in = min(1_000 · 100 / 10_000, 10_000)  = 10     // 1%, جيد تحت الحد
vault_received  = 1_000 − 10 = 990

pool_fee        = ceil(990 · 2_500 / 1_000_000)  = 3    // 0.25%
amount_after    = 990 − 3 = 987

amount_out_gross = 1_000_000 · 987 / (1_000_000 + 987) = 986_027 / ...  ≈ 985.97
```

≈ 985.97 USDC. لا رسوم نقل صادرة، لذا يستقبل المستخدم 985.97 USDC.

## مؤشرات

* [`/ar/products/cpmm/overview`](/ar/products/cpmm/overview) — دعم CPMM Token-2022.
* [`/ar/products/clmm/instructions`](/ar/products/clmm/instructions) — `SwapV2` مقابل `Swap` لتوجيه Token-2022.
* [`/ar/solana-fundamentals/spl-token-and-token-2022`](/ar/solana-fundamentals/spl-token-and-token-2022) — نموذج امتداد Token-2022 العام.

المصادر:

* [وثائق امتداد رسوم النقل في SPL Token-2022](https://spl.solana.com/token-2022/extensions#transfer-fees)
* مصدر برنامج Raydium CPMM (`SwapBaseInput` / `SwapBaseOutput` معالجة Token-2022).
* مصدر برنامج Raydium CLMM (`SwapV2`).
