本文深入探讨了 Solana Token-2022 中 interest-bearing 扩展的工作原理,该扩展允许 Token mint 自动累积利息,而无需链上余额更新。文章详细解释了利息计算模型,包括连续复利公式如何在链下计算利息,以及如何在钱包和应用程序中正确显示和处理这些余额。
Token-2022 的计息扩展功能允许 token mint 为该特定 mint 的所有 token 账户自动产生利息。它使用 mint 的链上配置中定义的年利率。
但是,此利息是一种计算视图:链上的实际 token 余额永远不会改变。相反,钱包和应用程序将连续复利公式应用于每个用户的链上余额,以计算其扣除应计利息后的余额。开发者可以将计算出的利息和链上余额合并为一个值或单独显示它们。
此扩展提供了用于计提利息的会计机制;它依赖于单独的 DeFi 应用程序来为利息提供经济支持。
在本文中,我们将分解计息扩展的架构,解释计算背后的数学原理,涵盖钱包兼容性,并通过一个使用 Anchor 的实际实现示例。
正如我们在 Token-2022 文章中讨论的那样,token 扩展是添加到 mint 或 token 账户的模块化功能。mint 账户的基本布局为 82 字节,token 账户的基本布局为 165 字节。扩展数据附加在这些基本大小之后,因此在创建 mint 或 token 账户之前,你必须分配等于基本大小加上任何已启用扩展大小的空间。
为计息扩展分配的空间存储扩展的数据,包括可以更新利率的授权账户字段。如果授权账户字段全为零,则将其视为 None,这意味着利率保持不变。在实践中,授权可以设置为 DeFi 应用程序,然后设置利率以反映应用程序中的实际经济活动。
除了授权字段之外,下面的 Rust 结构体(我们直接从扩展的源代码中获取)定义了完整的计息扩展数据:
initialization_timestamp),用作所有利息计算的开始时间pre_update_average_rate)。last_update_timestamp),用于计算应计利息current_rate)。/// 年利率,以基点表示
pub type BasisPoints = PodI16;
const ONE_IN_BASIS_POINTS: f64 = 10_000.;
const SECONDS_PER_YEAR: f64 = 60. * 60. * 24. * 365.24;
pub struct InterestBearingConfig {
/// 可以设置利率和授权的授权
pub rate_authority: OptionalNonZeroPubkey,
/// 初始化时间戳,从中进行利息计算
pub initialization_timestamp: UnixTimestamp,
/// 从初始化到上次更新时的平均利率
pub pre_update_average_rate: BasisPoints,
/// 上次更新的时间戳,用于计算累计总额
pub last_update_timestamp: UnixTimestamp,
/// 自上次更新以来的当前利率
pub current_rate: BasisPoints,
}
所有 Token-2022 扩展都遵循 Type-Length-Value (TLV) 格式,该格式允许程序轻松读取和跳过存储在账户中的不同扩展数据。
InterestBearingConfig TLV 条目编码为:
type): 0x0A ( InterestBearingConfig 的类型标识符)length): 0x34 ( u8,值 = 52 十进制)V ( value): 按顺序连接的序列化字段:
rate_authority (32 字节)initialization_timestamp (8 字节)pre_update_average_rate (2 字节)last_update_timestamp (8 字节)current_rate (2 字节)字段 pre_update_average_rate 和 current_rate 不存储为浮点数。相反,它们存储为 基点。
1 基点 = 1/100 (0.01%)
因此,要表示 2.50% 的年利率,你需要在 current_rate 字段中存储整数 250(因为 250 个基点是 250*1/100=2.5%)。要从百分比转换为基点,只需除以 0.01(或等效地,乘以 100)。在本例中,2.5 / 0.01=250。
在 InterestBearingConfig 扩展 TLV 布局中,V 部分是所有扩展字段按顺序连接的序列化值,如我们之前在 Token-2022 文章中所述。
例如,假设扩展包含以下值:
rate_authority:7xKXtg2CW87d9LN6HBUtjQVSiJ9MCrgdGubbyiTZRjrwb (32 字节)initialization_timestamp:1672531200 (2023 年 1 月 1 日;8 字节)pre_update_average_rate:500 (基点为 5.00%;2 字节)last_update_timestamp:1704067200 (2024 年 1 月 1 日;8 字节)current_rate:500 (基点为 5.00%;2 字节)当我们把上面的字段连接成一个连续的字节序列时,TLV 的 V (hex) 部分是:
0x689536DF68C2FB0A61A08DEDC9797145C969328A05D68A2A8C06E15A3AB6BD5200CDB06300000000F4018000926500000000F401
完整的 TLV 条目是 T(0x0A) | L(0x34) | V(...),并紧跟在 Mint 账户数据之后。

计息扩展初始化
计息扩展在一个操作中启用和初始化,该操作既保留空间又写入扩展的 TLV。正如我们之前在 Token-2022 文章中讨论的那样,
其他扩展通常需要两个步骤:
假设你在银行有一个储蓄账户。当你以 3% 的年利率存入 $1,000 时,你的账户对账单不会显示你的银行每天都在 mint 新的美元。相反,银行的系统会计算出如果复利计算,你的余额会增长多少,并在你登录时向你显示更新后的数字。
计息扩展使你的 mint 账户以类似的方式工作。你的链上余额(相当于你银行的余额)永远不会从 $1,000 改变。但是你的钱包(如网上银行应用程序)使用复利公式在六个月后显示显示 **** $1,015 ,或在一年后显示 $1,030。
如果银行稍后将你的利率从 3% 提高到 5%,则未来的利息复利会更快,但你之前的 3% 一年仍然是“锁定”,最终余额将正确反映该时期的 3% 增长率。
计息扩展使用连续复利公式 ( ) 来计算利息,并确保你的应计收益是准确的,无论利率是否变化(我们稍后将详细探讨此公式)。
该公式已硬编码到 Token-2022 程序中,有两种变体:最近一次费率更新的 before 和 after。
before 变体捕获早期利率下的增长(以防授权更新利率),而 after 变体捕获当前利率下的增长。它们共同产生一个连续的、时间加权的复利因子,确保余额在多个利率变化中保持准确。
接下来,让我们通过一个例子展示如何在数学上计算这些运算。
首先,这里是公式中变量的描述:
其中 SECONDS_PER_YEAR = 60 × 60 × 24 × 365.24
以下示例适用于利率未更改的情况:
**...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!