现代 Yield 协议:Pendle 的构建方式

  • mixbytes
  • 发布于 19小时前
  • 阅读 30

Pendle 是一个模块化的收益代币化协议,它将收益资产分解为本金代币(PT)和收益代币(YT),允许用户在二级市场上交易和管理收益。

简介

Pendle 是一个模块化的收益代币化协议,允许用户对其收益进行代币化并在二级市场中进行操作。Pendle 背后的主要思想是将产生收益的资产分成两部分:“本金”和“收益”,其中本金部分被锁定在协议中,直到到期日,而收益部分可以随时自由转换为基础收益。 本金和收益这两个部分都被代币化,并且可以在 AMM 池中交易,该池由协议为每种类型的收益创建,例如质押奖励(例如:stETH)、借贷协议中的供应奖励(例如:cToken)、激励奖励(CRV+CVX)和其他形式的收益。 这种方法实现了各种有趣的策略,允许用户不仅交易产生收益的资产,还交易“预计收益”,出售下降的收益并购买增加的收益。这些市场的一个重要特征是本金资产的低风险,所有风险都仅限于收益方面。

让我们来探讨一下这是如何运作的。

更高层面的概述

Pendle 上的每个产生收益的策略(例如,将资产提供给借贷协议)都有一组自己的两个代币:

  • 本金代币 (PT),代表投入该策略的资产本金金额。
  • 收益代币 (YT),代表所选策略产生的收益。

image.png

在所有情况下,PT_amount = YT_amount。另一个重要的不变量是 SY_value = PT_value + YT_value,这突出了 PT 和 YT 代币代表了底层资产的互补部分。随着市场接近到期日(此时 PT 代币变得完全可以赎回,而 YT 代币停止获得收益),PT 代币的价值增加,而 YT 代币的价值降低。这在代码中 此处此处 得到了证明,表明 PT 和 YT 的费率取决于 market.expiry - blockTime。

PT 和 YT 代币提供了与本金和收益部分进行交互的灵活方式,通过利用几乎所有现代 DeFi 项目的代币进行收益代币化,从而支持单个 YT 的多个奖励代币。当用户将产生收益的资产(例如 stETH、cUSDT、yvUSDC)存入 Pendle 时,他们会收到等量的 PT 和 YT 代币,然后他们可以独立交易这些代币。由于 DeFi 项目的 APY 是动态的,因此这种机制为 YT 代币创造了一个独特的市场,该市场基于收益估算而不是简单的代币价格运作。

DeFi 协议中不同类型的收益需要不同的方法。一些协议使用可重新抵押的代币,如 stETH(来自 Lido)或 aTokens(来自 Aave),另一些则依赖于外部利率,如 cTokens(来自 Compound)或 wstETH(来自 Lido)。一些协议具有由用户活动驱动的可变行为,例如 CRV/CVX(来自 Curve/Convex),而另一些协议则从外部收益策略中获得代币,例如 yvUSDC(来自 Yearn)。在这些不同的案例中实施 PT 和 YT 需要一个统一的收益代币化标准,这在 Pendle 的标准化收益 白皮书 中有所概述。该标准允许像 stETH、cDAI 和 yvUSDC 这样的代币被包装成 SY-stETH、SY-cDAI 和 SY-yvUSDC 代币,并在 Pendle 协议中进行标准化操作。

当创建一个新的 SY(标准化收益)实例时,Pendle 会启动一个 AMM,在该 AMM 中可以交易相应市场的 PT 和 YT 代币,从而使收益从一开始就可以进行交易。让我们用一个例子来说明这一点:

• Alice 代币化了 100 SY 并收到了 100 PT + 100 YT。

• Alice 在市场上将她的 100 YT 出售给 Bob。

• Bob 现在持有 100 YT,而 Alice 保留 100 PT。

ᅠ◦ 该系统总共持有 100 PT 和 100 YT 的供应量。

• Bob 通过市场将他的 YT“赎回”为 SY:

ᅠ◦ 市场使用其可用的 PT 来匹配 Bob 的 YT。

ᅠ◦ 该对(PT + YT)被赎回为 SY。

ᅠ◦ Bob 收到 SY(减去费用)。

ᅠ◦ PT + YT 的总供应量减少了相同的数量。

AMM 确保任何被赎回的 YT 都会与系统中等量的 PT 相匹配,从而保持全局供应不变性。

总之,尽管用户可以单独交易 PT 和 YT 代币,但该协议确保代币销毁始终保持两者之间的平衡。

让我们来看看这是如何实现的。

MarketFactory

让我们从在 PendleMarketFactoryV3.sol 中创建一个新市场开始。每个市场的核心都是一个 PT 代币,它被 用作 市场的主要“标识符”(映射中的 PT 键)。

在创建一个新的 SY 实例时,遇到的一个关键参数是 scalarRoot。此参数在“塑造”市场的行为方面起着重要作用,影响诸如价格影响和套利效率之类的因素。基本概念是,在未来日期承诺的资产今天的价值较低,从而产生折扣,该折扣定义了 PT 价格(相对于 YT 价格)。scalarRoot 确定价格曲线是更陡峭还是更平坦,具体取决于到期日之前的 时间,并用于 PT 代币汇率 计算 中。

_getRateScalar() 随着到期日的临近而增加,这意味着在市场的“早期”阶段,价格影响较小,允许更大的 PT 交易。随着到期日的临近,价格敏感性增加,鼓励做市商将市场重新平衡到更接近公平价值。这种机制确保 PT 价格逐步与其到期时的赎回价值保持一致,所有这些都不依赖于外部预言机或手动调整。

另一个重要参数 initialAnchor 代表 初始 汇率。它决定了市场池中 PT 和底层代币的初始分配。initialAnchor 和 scalarRoot 共同塑造了价格曲线,该曲线在到期时收敛到底层代币的实际价值。

该曲线支撑了 Pendle 的主要用例:以市场决定的利率交易今天的未来收益。

此外,PendleMarketFactoryV3 包括两个与治理相关的 函数,用于设置国库费用和地址,以及定义一个特殊的 overriddenFee,该费用在需要时 取代 标准市场费用。

Pendle 代币

如前所述,所有 Pendle 逻辑都围绕 SY 代币及其衍生物:PT 和 YT 代币。有关包装的产生收益的有用信息可以在 Pendle 提出的 EIP-5115 中找到。

让我们从 PT 和 PendlePrincipalToken 合约开始,该合约相对简单。它由代币工厂创建,包括一个 isExpired 检查(针对到期日),并且只能 与相应的 YT 代币同步销毁或铸造。

另一方面,PendleYieldToken (YT) 则复杂得多。它包含 铸造销毁 使用 SY 代币的同步对 (PY) PT+YT 代币的函数。这些函数是许多 Pendle 操作不可或缺的一部分,因为用户只需要 YT 或 PT 代币的任何操作都涉及铸造或销毁 SY 代币,接收“同步”数量的 PT 和 YT 代币,然后利用此对的所需部分。

此外,代表收益的 YT 代币包含用于利息累计的函数。它具有 _pyIndexCurrent() 函数,该函数返回当前的汇率。此函数广泛用于基于当前累计收益计算 PT 和 YT 代币数量的计算中。此索引的一个关键用途是确定来自给定 PT 和 YT 代币的目标 SY 数量(在代码中组合为“PY”),反之亦然(示例可以在 此处此处 找到)。在这些函数中,该索引充当 SY 和 PT(或 YT)代币之间的交换

让我们考虑一个涉及 Pendle 中收益累计的示例场景:

  • Alice 将 1000 USDC 存入 Aave,收到 1000 aUSDC,并在 Pendle 中将其包装成 1000 SY-aUSDC。
  • Alice 使用 mintPY() 从她的 SY-aUSDC 中铸造 PT+YT 代币,并收到与当前索引相对应的等量的 PT 和 YT 代币(例如,1000 PT 和 1000 YT)。
  • Alice 等待她的 aUSDC 产生收益;例如,1000 aUSDC 变为 1020 aUSDC。
  • pyIndex 增加,因此 现在 赎回 PT 和 YT 代币会导致更多的 SY-aUSDC 代币。
  • Alice 将她的 1000 PT + 1000 YT 代币赎回为 1020 SY-aUSDC。

此示例描述了最简单的情况。在任何中间时刻,Alice 都可以独立地在 Pendle 的 AMM 中交易 PT 和 YT 代币,并在以后“组合”PT 和 YT 代币以将其 aUSDC 赎回为 SY 代币。她可以专注于 YT 代币,假设收益会增加,或者专注于 PT 代币,假设收益率可能会下降。或者,她可以简单地投机 PT 和 YT 代币。

现在,让我们继续 Pendle 市场。

市场(Market)

Pendle 市场位于 PendleMarketV3.sol 合约中。此合约充当 ERC20 PENDLE-LPT 代币,代表用户在市场中的份额。市场使用 三种 代币运行,这些代币在部署期间 配置 为不可变的:SY、PT 和 YT 代币。代币的总供应量在 MarketStorage 结构中跟踪。如前所述,收益曲线参数和 PT 代币到期日最初是 设置 的。

首先,我们需要重点介绍 mint()burn() 函数,这些函数充当市场代币之间交换的流动性提供机制。在这种情况下,流动性提供者从这些交换中赚取费用。

现在,让我们看一下最重要的函数:swapExactPtForSyswapSyForExactPt。这些函数允许用户将 SY 代币交换为 PT 代币,反之亦然。回想一下,SY 代币由 PT 和 YT 代币组成,这意味着 SY 代币的持有者同时拥有“固定利率”部分 (PT),在到期时保证一定数量的底层代币,以及“收益”部分 (YT)。这些 SY↔PT 转换允许用户从“固定”保证头寸转移到更有利可图但风险更高的“收益”头寸。

例如:Alice 拥有来自 6 个月市场的 1,000 个 USDC 本金代币 (PT),该市场将在 3 个月后到期。她认为利率将显着上升,与市场上可用的可变收益相比,她的固定利率头寸吸引力较小。为了适应,她将她的 PT 代币交换为 SY 代币(同时拥有 PT 和 YT),并开始以现行市场利率累积收益。

另一个例子:如果 Alice 担心她的 stETH 持有量的潜在利率下降并持有 SY-stETH 代币,她可以出售她的 YT 代币并购买 PT 代币。此操作使她在到期时获得更可预测的结果,锁定固定回报率,而不是暴露于可变收益率。

还有一些有趣的情况涉及具有相同底层产生收益资产的多个市场。请参阅此屏幕截图:

image.png

在上图中,具有不同到期日期的三个市场都有自己的 YT 代币,这些代币获得相同的底层收益。关心收益率的用户可以通过在一个市场购买 YT 代币并在另一个市场出售 YT 代币来利用这一点。例如,如果他们认为短期利率的下降速度快于长期利率,他们可能会在“短期”市场购买 YT 代币,并在“长期”市场出售 YT 代币(使用转换为底层代币)。“长期”市场中的 YT 代币将较少受到这些利率变化的影响。此功能提供了以前仅在传统金融中可用的复杂固定收益交易策略。

我们将在后面的章节讨论用户场景时进一步探讨 swapExactPtForSy() 和 swapSyForExactPt() 函数。这四种代币(底层代币、SY、PT、YT)的组合支持各种潜在应用,我们无法在本文中完全涵盖。

现在,让我们继续路由器,它将市场和所有参与代币结合在一起,并描述一些示例场景。

路由器(Router)

路由器充当用户与协议交互的入口点。它被组织为多个 Action[...] 合约,其中包含各种类型的逻辑。虽然审查这些合约中的所有函数对于本文来说会过多,但检查一个特定的用户场景并跟踪涉及的函数是有用的。所以...

想象一下,由于即将到来的协议变更,Alice 预计 stETH 收益将显着增加。她决定获取 YT 代币以利用这种潜在的优势。

她首先使用 swapExactTokenForYt() 函数,批准一定数量的 WETH 并提供市场地址、代币输入详细信息(WETH、数量等)、最小 YT 输出(以考虑滑点)和其他参数(其中一些将在稍后描述)。首先,该函数 检查 是否可以使用近似值 — 一种我们稍后将讨论的优化。Alice 铸造 SY 代币,将底层代币 包装 到它们的“SY”版本中。

下一步涉及使用 _swapExactSyForYt() 函数将这些 SY 代币 交换 为 YT 代币,该函数内部很复杂。在此交换(SY 到 YT 代币)期间,Pendle 首先尝试填写限价单,但这与 Alice 的情况无关(我们不打算讨论限价单,因为它会分散我们对主要机制的注意力)。

然后,Alice 通过 approxSwapExactSyForYtV2() 函数 计算 通过该函数她将收到的 YT 代币数量,该函数尤其值得注意。此函数使用数值近似来计算应从交换指定数量的 SY 代币产生的最佳 YT 代币数量。

此处 进行了优化。如果智能合约使用迭代算法进行近似、优化或搜索,用户可以使用外部(例如,来自链下 dApp)通过为该算法提供建议的起始值来帮助它。这些提示可以加速计算过程。这项技术并不新鲜,如 Liquity V2 ( 文章) 中用于链表的 getAppoxHint() 函数所示。在这种情况下,用户提供的 ApproxParams 有助于计算最佳 YT 代币数量。

[注意] 这种“用户提供的提示”方法并非完全万无一失,如果其他交易在计算过程中更改合约状态,可能会变得无效,从而导致 gas 效率低下,甚至导致 griefing 攻击。在 Pendle 中,这可以通过池中的失衡保护来缓解,从而防止代币汇率突然变化。

如果未提供外部 approx 参数,则该函数 使用 来自当前市场的最小值/最大值。

接下来,该函数开始一个 循环,估计需要涉及多少 PT 才能有效地将确切的 SY 输入转换为 YT 代币。由于 PT 和 YT 代币必须以相等的数量铸造,但价格不同,因此近似算法确定了给定 SY 输入所需的 最佳 PT 数量,以在可接受的误差范围内最大化 YT 输出。这确定了实现目标 YT 数量需要多少 SY 代币。

最后,是时候 赎回 SY 代币,仅提取 YT 代币,因为 Alice 只需要她支付的 YT 代币。这里出现了一个有趣的方面:接收者 是 YT 代币合约(不是接收者)。这可以通过交换期间的以下操作顺序来解释:

  • 从一些初始 SY (PT + YT) 开始。
  • “闪电借款”达到目标 YT 数量所需的 PT 代币。
  • 使用从市场上借入的 PT 代币购买额外的 SY 代币。
  • 组合初始和“部分借入”的 SY 代币。
  • 从此组合的 SY 金额中铸造 PT + YT 代币。
  • 使用 PT 代币偿还闪电贷。
  • 保留 YT 代币作为最终输出。

虽然该过程看起来很复杂,但结果很简单:Alice 最终获得了使用基础资产获得的 YT 代币(可在 AMM 中交易)。对于反向交换,可以使用 swapExactYtForToken() 函数将 YT 代币交换为其他资产。

Pendle 路由器还包括用于涉及 PT 代币的交换的类似函数:swapExactTokenForPt()swapExactSyForPt()swapExactPtForToken()swapExactPtForSy()。所有这些函数都依赖于 SY 代币作为中间资产。

AMM

接下来,让我们探索 Pendle 的 AMM,它促进使用 SY、PT 和 YT 代币进行交易。AMM 在特定的市场中运行,而定义各种操作后 AMM 的源状态和目标状态的数学逻辑位于 MarketMathCore 库合约中。

如前所述,Pendle 的 AMM 支持流动性提供。让我们简要查看 addLiquidityCore()removeLiquidityCore() 函数,这些函数管理总的 SY 和 PT 储备,并计算铸造或销毁的 LP 份额数量。这些函数还向协议储备中添加了一个 MINIMUM_LIQUIDITY 数量,以防止抢跑交易初始存款。初始价格被设定为初始 SY 和 PT 存款的几何 均值。这两个函数利用 SY 和 PT 数量中的 较小值 来进行已发行/销毁份额的计算。

最有趣的组件之一是 calcTrade() 函数,负责与 PT、YT 和 SY 代币之间的交换相关的数学计算。它考虑了由市场价格曲线决定的交换 汇率。进一步检查 _getExchangeRate() 函数:

  • 我们计算 比例,表示 PT 代币与总池价值的比率。
  • 如果交换导致比例超过 MAX_MARKET_PROPORTION(96%),我们将阻止交换,以防止池中的大规模失衡。
  • 我们 应用 *l*n(proportion/1−proportion) 来为更大的池失衡创造更极端的汇率。基本上,池越是偏离均衡,推动其进一步向该方向移动的成本(以价格影响而言)就越高。
  • 我们 调整 汇率,使用市场特定的 rateScalar 和 rateAnchor 参数,使得随着到期的临近,AMM 对池失衡的敏感性越来越高(rateScalar 增加)。
  • 如果最终汇率 < 1, 阻止 交换,因为 PT 代币的价值不能低于 SY 代币,同时保持其作为代表至少基础资产价值的本金代币的经济属性。

这种设计独特地结合了时间敏感性和对池代币余额的敏感性,使 Pendle 的 AMM 在收益交易市场中特别有效。

交换费用以 SY 代币 的形式收取,并在协议储备和市场之间分配。储备的费用归市场财政所有(如这里所示这里),而剩余的费用则留在市场中,为 LP 创造收益。

价格预言机

PendlePYOracleLib 库为 PT 和 YT 代币提供价格预言机。这些预言机利用 SY 和 PT 指数

有趣的是,存在一种“棘轮”机制。如果基础资产遭受损失(由于黑客攻击、削减等),SY 指数会下降。然而,PT 持有者必须通过获得公平数量的 SY 代币来保护自己免受这些损失。为此,PY 指数被设计为永不下降,充当“棘轮”机制。当 SY 指数下降时,PT 指数“冻结”,保持不变,直到 SY 指数恢复并“追赶”。一旦发生这种情况,两个指数将继续一起上升:

img

因此,返回的 PY(PT 和 YT)指数被选为 SY 和 PY 指数 的最大值。在 所有 返回 PT 和 YT 代币汇率的函数中,都有条件,例如 这个,调整汇率计算以考虑 SY 指数和 PY 指数之间的差异。此外,根据 Pendle 不变式 SY_value = PT_value + YT_value,任何损失都由 YT 持有者“吸收”。在此期间,YT 持有者不会获得任何收益,YT 代币价格甚至可能变为负值。

Pendle 还为其 LP 代币提供预言机 (PendleLpOracleLib),这些预言机也依赖于 SY 和 PY 指数。这些预言机使用 相同 的汇率调整来确定 LP 代币的价值。

该机制为 PT 赎回价值建立了一个“底线”,以基础代币的形式。PT 代币将始终可以按可预测的数量赎回基础 SY 代币。然而,需要注意的是,如果出现问题,基础资产中 SY 代币的价值可能会波动。

实现细节

Pendle 采用了许多值得一提的有趣的机制。其中之一是在 MarketPreCompute 结构体中“缓存”重要的市场信息。在函数中,计算所需的当前市场值(例如 rateScalarrateAnchor)一次,然后重复使用。这对于执行迭代的函数至关重要,例如 approxSwapExactSyForYtV2(),它在每次迭代中都需要这些值。

另一个值得注意的特性是 PendleMarketV3 中的 skim() 函数,它将任何多余的 PT 和 SY 代币转账到金库。这允许协议处理由于舍入误差、不正确的直接转移到池中、黑客攻击等导致出现“无法解释”的代币的情况。

此外,还有一个 overriddenFee,可以由特定的路由器设置,以覆盖市场费用。此功能可以通过合作协议鼓励集成,或者供有资格享受降低费用的高交易量路由器使用。

最后,Pendle 包括一个与治理和激励措施相关的重要的组件量规。这涉及 vePENDLE 代币,它不在此协议审查的范围内。

结论

Pendle 协议是现代 DeFi 解决方案的一个很好的例子。它能够将多个 DeFi 协议的本金和收益部分代币化为单独的资产,使用户可以交易他们对协议在不同时期内表现的期望和担忧。这为收益代币化开辟了广泛的用例,包括全新的策略。

Pendle 包含几个值得研究的令人印象深刻的功能:

  • 一种统一的标准 (SY),可以与各种生息资产兼容。
  • 能够在同一底层资产的多个市场上交易长期和短期收益。
  • 一种复杂的 AMM,它结合了时间敏感性和不平衡敏感性,专为收益交易而设计。
  • 保护协议免受操纵、不平衡和底层资产波动的预言机和汇率。
  • 灵活的费用系统,为特定路由器提供覆盖费用。
  • 一个全面的量规系统,用于流动性激励。

所有这些创新都将 Pendle 定位为一个“新浪潮”项目,其中链上资产可以与传统金融工具的复杂性相媲美,甚至超越它们。

感谢你的阅读,我们下篇文章见!

  • MixBytes是谁?

MixBytes 是一支由专业的区块链审计员和安全研究人员组成的团队,专门为与 EVM 兼容的和基于 Substrate 的项目提供全面的智能合约审计和技术咨询服务。在 X 上加入我们,以随时了解最新的行业趋势和见解。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
mixbytes
mixbytes
Empowering Web3 businesses to build hack-resistant projects.