Skip to main content
本頁內容由 AI 自動翻譯,所有內容以英文版本為準。查看英文版 →
支援矩陣:CPMM 完全支援 Token-2022,包括轉帳費用代幣。CLMM 透過明確的 SwapV2 帳戶支援轉帳費用的 Token-2022。AMM v4 完全不支援 Token-2022。LaunchLab 透過 InitializeV2 建立經典 SPL 基礎代幣,但有專用的 InitializeWithToken2022 進入點,可建立 Token-2022 基礎代幣並選擇性地附加 TransferFeeConfig;其報價端接受任一代幣程式。參見 products/launchlab/platform-configFarm v6 在質押和獎勵代幣上都支援 Token-2022。

什麼是轉帳費用

Token-2022 是第二個 SPL Token 程式(TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DATokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb)。在其擴展中,轉帳費用擴展使得每次在代幣鑄造上進行 TransferChecked 都會從轉帳金額中扣除費用。費用會路由到由鑄造權限人指定的收款人,並且可由權限人更新(在限制範圍內)。 具有轉帳費用的鑄造有兩個相關參數:
  • transfer_fee_basis_points — 費率(例如 100 = 1%)。
  • maximum_fee — 每次轉帳的絕對上限(這樣大額轉帳者就不會支付無限制的費用)。
一個鑄造可以同時有兩個活躍的轉帳費用配置:「較新」的(現在生效)和「較舊」的(正在排程退出)。這是「時期轉換」設計 — 轉帳費用變更在時期邊界生效,以避免對進行中的交易造成驚訝。

為什麼這對交換很重要

池的金庫持有實際餘額。當使用者呼叫 Raydium 交換時:
  1. 使用者將 amount_in 發送到池金庫。如果入金代幣有轉帳費用,金庫收到的是 amount_in − fee_in,而不是 amount_in
  2. 交換數學在金庫收到的金額上運作。
  3. 池將 amount_out 發送到使用者的 ATA。如果出金代幣有轉帳費用,使用者收到的是 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,透過 TransferChecked 將其發送給使用者,Token-2022 程式本身會將其減少轉帳費用。
使用者的 minAmountOut 滑點界限是針對 out_gross(池發送的)檢查的,不是針對使用者收到的。這是每個主要 Solana DEX 處理 Token-2022 的方式,這很重要,因為:
  • 如果池檢查費後金額,報價和執行之間的費用更新會導致交易回復。
  • 檢查費前金額將失敗固定在報價本身的品質上,而不是使用者的帶外費用變更。
UI 應在向使用者顯示「你將收到」時減去預期的 Token-2022 轉帳費用。

計算 Token-2022 費用

SPL Token-2022 程式公開了一個確定性的輔助函數。在 Rust 中:
在 TypeScript 中(透過 @solana/spl-token):

調整後的交換公式(CPMM,精確輸入)

f_pool 為池費率,f_in 為入金代幣轉帳費率,max_in 為其最高上限,f_out 為出金代幣轉帳費率,max_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
max_in / max_out 上限使計算非線性,因為一旦達到上限,費用就停止增長。SDK 的 computeAmountIn / computeAmountOut 透過在天真公式會超過上限時迭代來處理。

邊界情況

非對稱費用(一側有費用,另一側沒有)

在實踐中很常見。上面的公式已經處理了這種情況 — 如果一側有 f_in = 0,相關項會消失。程式中沒有特殊情況。

交換中途的費用更新

如果鑄造的轉帳費用在報價時間和執行時間之間變更,交換要麼以略差的經濟狀況著陸(使用者在滑點容限內承擔差異),要麼回復(毛輸出下降到 minAmountOut 以下)。滑點界限吸收了這一點;不需要額外保護。

最高費用上限

一旦交易足夠大以達到 maximum_fee,費用飽和,進一步增長為零。這使得對於非常大的交易,有效費率漸近於零,這可能在深度流動性不足的市場上造成奇怪的定價曲線。SDK 的 computeAmountOut 考慮了這一點。

不可轉帳擴展

某些 Token-2022 鑄造使用 NonTransferable 擴展,它拒絕除了往返鑄造權限人之外的所有 Transfer 呼叫。這樣的鑄造根本無法在 Raydium 池中使用。CreatePool 在初始化時拒絕它們。

計息代幣

Token-2022 也支援 InterestBearingConfig 擴展,使餘額隨時間增長。Raydium 的池讀取原始金庫餘額(忽略利息應計),所以在具有計息代幣的池上,LP 在贖回時捕獲應計利息作為純禮物(金庫餘額增長速度快於 LP 供應表示)。整合者應將其視為非問題,但應為 LP 端記錄。

轉帳掛鉤

Token-2022 的 TransferHook 擴展允許在每次轉帳上進行任意 CPI。Raydium CPMM 支援這些 — 交換指令轉發掛鉤帳戶 — 但它增加了 CU 開銷並要求掛鉤表現良好。CLMM SwapV2 也支援掛鉤。AMM v4 完全不支援 Token-2022,所以這個問題不會出現。

實際例子

CPMM 池,x = 1_000_000 USDY, y = 1_000_000 USDC,池費 0.25%。
  • USDY 有 1% 轉帳費用,max_fee = 10_000(6 位小數的 0.01 USDY)。
  • USDC 沒有轉帳費用。
使用者交換 amount_in = 1_000 USDY 以換取 USDC(精確輸入)。
≈ 986.03 USDC。沒有出站轉帳費用,所以使用者收到 ≈ 986.03 USDC。

參考資源

來源: