Chuyển đến nội dung chính

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.

Trang này được dịch tự động bằng AI. Phiên bản tiếng Anh là bản chính thức.Xem bản tiếng Anh →
Ma trận hỗ trợ: CPMM hỗ trợ Token-2022 đầy đủ, bao gồm mint có phí chuyển. CLMM hỗ trợ Token-2022 với phí chuyển thông qua account SwapV2 rõ ràng. AMM v4 không hỗ trợ Token-2022 hoàn toàn. LaunchLab không hỗ trợ Token-2022 cho mint cơ sở (nó tạo mint SPL cổ điển). Farm v6 hỗ trợ Token-2022 trên cả mint đặt cọc và mint phần thưởng.

Phí chuyển là gì

Token-2022 là chương trình Token SPL thứ hai (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DATokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb). Trong số các extension của nó, extension transfer-fee khiến mọi lệnh TransferChecked trên mint token đều trừ một khoản phí từ số tiền được chuyển. Phí được định tuyến tới người nhận được chỉ định bởi mint authority và có thể được cập nhật bởi authority (trong các giới hạn). Một mint có phí chuyển có hai tham số liên quan:
  • transfer_fee_basis_points — tỷ lệ (ví dụ 100 = 1%).
  • maximum_fee — giới hạn tuyệt đối cho mỗi lần chuyển (để những giao dịch khổng lồ không phải trả phí vô hạn).
Một mint có thể có hai cấu hình phí chuyển hoạt động cùng lúc: cái “mới hơn” (có hiệu lực ngay bây giờ) và cái “cũ hơn” (đang được lên lịch loại bỏ). Đây là thiết kế “chuyển đổi epoch” — những thay đổi về phí chuyển có hiệu lực trên ranh giới epoch để tránh làm giật ngạc nhiên các giao dịch đang diễn ra.

Tại sao điều này quan trọng đối với swap

Vault của pool nắm giữ các số dư thực tế. Khi bạn gọi swap Raydium:
  1. Bạn gửi amount_in tới vault pool. Nếu in-mint có phí chuyển, vault nhận được amount_in − fee_in, không phải amount_in.
  2. Toán học swap hoạt động trên số tiền vault nhận được.
  3. Pool gửi amount_out tới ATA của bạn. Nếu out-mint có phí chuyển, bạn nhận được amount_out − fee_out, không phải amount_out.
Nếu chương trình swap không chính xác và sử dụng tham số amount_in thô, kiểm tra bất biến sẽ thất bại vì vault nhận được ít hơn những gì chương trình nghĩ. Ngược lại, nếu nó tính amount_out mà không trừ đi phí chuyển outbound, bạn sẽ thấy thiếu hụt và đổ lỗi cho chương trình. Raydium CPMM và CLMM (thông qua SwapV2) xử lý điều này bằng cách:
  • Pre-swap: tính toán in_after_fee = amount_in − transfer_fee_on(amount_in, in_mint), và sử dụng in_after_fee trong toán học đường cong.
  • Post-swap: tính toán out_gross = amount_out_from_curve, gửi out_gross tới bạn qua TransferChecked mà chương trình Token-2022 sẽ tự động giảm bớt bằng phí chuyển.
minAmountOut về slippage của bạn được kiểm tra so với out_gross (những gì pool gửi), không phải so với những gì bạn nhận được. Đây là cách mọi DEX Solana chính hãng xử lý Token-2022, và nó quan trọng vì:
  • Nếu pool kiểm tra post-fee, một cập nhật phí giữa quote và thực thi sẽ khiến giao dịch hoàn lại.
  • Kiểm tra pre-fee ghim lỗi vào chất lượng của quote, không phải vào những thay đổi phí ngoài dòng của bạn.
UI nên trừ phí chuyển Token-2022 dự kiến khi hiển thị “Bạn nhận được” cho bạn.

Tính phí Token-2022

Chương trình SPL Token-2022 cung cấp trợ giúp xác định được. Trong 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;
Trong TypeScript (thông qua @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));

Công thức swap điều chỉnh (CPMM, exact-input)

Gọi f_pool là tỷ lệ phí pool, f_in là tỷ lệ phí chuyển in-mint, max_in là giới hạn tối đa của nó, f_out là tỷ lệ phí chuyển out-mint, max_out là giới hạn tối đa của nó.
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
Kiểm tra slippage: amount_out_gross ≥ min_amount_out (không phải user_receives ≥ min_amount_out). minAmountOut của bạn được đặt bởi SDK thành expected_gross · (1 − slippage) — giữ giới hạn ở phía “gửi”, không phải phía “nhận”.

Công thức điều chỉnh (CPMM, exact-output)

SDK lặp lại để tìm amount_in sao cho user_receives = amount_out_exact:
# bạn muốn nhận amount_out_exact sau phí chuyển
amount_out_gross = amount_out_exact + transfer_fee_out_for(amount_out_exact)

# sau đó giải CPMM exact-output cho amount_after:
amount_after     = ceil(x · amount_out_gross / (y − amount_out_gross))

# sau đó thêm phí pool:
vault_received   = ceil(amount_after · 1_000_000 / (1_000_000 − f_pool))

# sau đó thêm phí chuyển in:
amount_in = ceil(vault_received · 10_000 / (10_000 − f_in))
# (hoặc lặp lại — xem trường hợp cạnh cap phí bên dưới)
Các cap max_in / max_out làm cho phép tính trở nên phi tuyến tính vì khi đạt được cap, phí dừng tăng. computeAmountIn / computeAmountOut của SDK xử lý điều này bằng cách lặp lại nếu công thức ngây thơ sẽ đẩy quá cap.

Trường hợp đặc biệt

Phí không đối xứng (một bên có phí, bên kia không)

Phổ biến trong thực tế. Các công thức trên đã xử lý điều này — nếu một bên có f_in = 0, các điều khoản liên quan sẽ sụp đổ. Không có trường hợp đặc biệt trong chương trình.

Cập nhật phí giữa swap

Nếu phí chuyển của mint thay đổi giữa thời gian quote và thời gian thực thi, swap sẽ hoặc hạ cánh với kinh tế hơi tồi tệ hơn (bạn chịu sự khác biệt trong dung sai slippage) hoặc hoàn lại (đầu ra gross giảm dưới minAmountOut). Giới hạn slippage hấp thụ điều này; không cần bảo vệ bổ sung.

Giới hạn phí tối đa

Khi giao dịch đủ lớn để đạt maximum_fee, phí bão hòa và mức tăng thêm là không. Điều này làm cho tỷ lệ hiệu quả tiệm cận đến không cho những giao dịch rất lớn, có thể gây ra những đường cong định giá kỳ lạ trên những thị trường vô cùng không có tính thanh khoản. computeAmountOut của SDK tính đến điều này.

Extension không thể chuyển

Một số mint Token-2022 sử dụng extension NonTransferable, từ chối tất cả các lệnh Transfer trừ tới và từ mint authority. Những mint như vậy không thể được sử dụng trong pool Raydium hoàn toàn. CreatePool từ chối chúng khi khởi tạo.

Mint có lãi suất

Token-2022 cũng hỗ trợ extension InterestBearingConfig khiến số dư dường như tăng theo thời gian. Pool của Raydium đọc số dư vault thô (bỏ qua lãi suất accrual), vì vậy trên pool có mint có lãi suất, LP nắm bắt lãi suất đã tích lũy như một món quà thuần túy bất cứ khi nào họ hoàn lại (số dư vault tăng nhanh hơn biểu diễn cung cấp LP). Người tích hợp nên coi đây là vấn đề không cần quan tâm nhưng nên ghi lại cho phía LP.

Transfer hooks

Extension TransferHook của Token-2022 cho phép CPI tùy ý trên mọi lần chuyển. Raydium CPMM hỗ trợ những cái này — hướng dẫn swap chuyển tiếp các account hook — nhưng nó thêm chi phí CU và yêu cầu hook có hành vi tốt. CLMM SwapV2 cũng hỗ trợ hook. AMM v4 không hỗ trợ Token-2022 hoàn toàn, vì vậy câu hỏi không phát sinh.

Ví dụ thực tế

Pool CPMM, x = 1_000_000 USDY, y = 1_000_000 USDC, phí pool 0.25%.
  • USDY có phí chuyển 1%, max_fee = 10_000 (0.01 USDY với 6 chữ số thập phân).
  • USDC không có phí chuyển.
Bạn swap amount_in = 1_000 USDY cho USDC (exact-input).
transfer_fee_in = min(1_000 · 100 / 10_000, 10_000)  = 10     // 1%, well under cap
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. Không có phí chuyển outbound, vì vậy bạn nhận được 985.97 USDC.

Con trỏ

Nguồn: