الانتقال إلى المحتوى الرئيسي

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

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

Token-2022 هو برنامج SPL Token الثاني (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DATokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb). من بين امتداداته، فإن امتداد 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:
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):
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.

مؤشرات

المصادر: