本文目录导读:

这是一个非常好的问题,因为它触及了 Pendle 协议最核心的创新点:将生息资产的“本金”与“未来收益”进行分离交易。
Pendle 让用户能够将一笔会产生利息的资产(在 Lido 上的 stETH,在 Aave 上的 USDC 存款凭证)拆分成两个独立的、可交易的代币:
- SY (Standardized Yield Token):代表资产的本金。
- YT (Yield Token):代表资产在未来一段时间内(比如6个月或1年)的所有收益。
下面我们来详细拆解这个“收益分离”的过程及其背后的逻辑,以一个完整的 PHP 项目(或伪代码)视角来理解,并给出一个具体的实现思路。
核心概念与流程
想象你买了 1 个 stETH(假设价值 1 ETH),它在 Lido 里每年会产生 5% 的年化收益,如果你把这个 1 stETH 存入 Pendle,系统会做两件事:
- 铸造 (Mint) 出 1 个 SY-stETH:这个代表你的本金权利,到期后,你可以用这个 SY 换回 1 个 stETH。
- 铸造 (Mint) 出一定数量的 YT-stETH:这个代表未来一年的全部收益,假设一年收益是 0.05 stETH,那么这个 YT 就代表索取这 0.05 stETH 的权利。
关键分离点:这两个代币可以独立在市场上交易。
- 如果你是保守型投资者:你可以立刻卖出 YT,收回现金,然后长期持有 SY,这样你就锁定了未来收益(虽然卖了,但到手现金),本金在到期后完整返还,这就是“固定收益”。
- 如果你是激进型投资者:你可以买入大量 YT,赌未来收益率会更高(Lido 年化涨到 10%),或者赌市场情绪会让 YT 价格飙升。
PHP 项目实现思路
在 PHP 中实现这样一个“收益分离”系统,并不需要直接与 EVM 交互(除非要写合约),而是需要构建一个状态机和交易引擎,我们可以模拟一个 DeFi 协议的后端逻辑。
项目结构(示例)
<?php
// src/Models/PendlePool.php
class PendlePool {
public string $poolId; // e.g., "stETH-26DEC2024"
public string $underlyingAsset; // e.g., "stETH"
public float $apy; // 年化收益率
public DateTime $maturityDate; // 到期日
public float $totalSySupply; // 总SY供应量
public float $totalYtSupply; // 总YT供应量
}
铸造(Mint):分离本金与收益
这是最核心的函数,用户存入 amount 数量的生息资产(SY 的上游),系统为其铸造等量的 SY 和未来定量的 YT。
<?php
// src/Services/PendleMath.php
class PendleMath {
/**
* 计算给定APY和到期时间,一个单位本金未来会产生多少YT收益。
* @param float $apy 年化收益率 (0.05 表示 5%)
* @param DateTime $maturityDate 到期日
* @return float 单位本金对应的YT数量
*/
public static function calculateYtAmountPerSy(float $apy, DateTime $maturityDate): float {
$now = new DateTime();
$secondsInYear = 365.25 * 24 * 3600;
$timeToMaturity = $maturityDate->getTimestamp() - $now->getTimestamp();
$yearsToMaturity = $timeToMaturity / $secondsInYear;
// 简化:假设复利简单计算 (实际生产环境使用complex yield math)
// 年化5%,6个月后到期,则每个本金产生 0.05 * 0.5 = 0.025 个YT
return $apy * $yearsToMaturity;
}
/**
* 铸造SY和YT
* @param PendlePool $pool
* @param float $depositAmount 用户存入的生息资产数量
* @return array ['syAmount' => float, 'ytAmount' => float]
*/
public static function mintSyAndYt(PendlePool $pool, float $depositAmount): array {
$syAmount = $depositAmount; // 1:1
$ytAmount = self::calculateYtAmountPerSy($pool->apy, $pool->maturityDate) * $depositAmount;
// 更新池子总供应量
$pool->totalSySupply += $syAmount;
$pool->totalYtSupply += $ytAmount;
return [
'syAmount' => $syAmount,
'ytAmount' => $ytAmount,
];
}
}
赎回(Redeem):合并本金与收益
到期日之后,用户可以持有 SY + 需要的 YT 来赎回原始的底层资产(stETH),1 个 SY 加上若干数量的 YT(或直接拿着 YT 去兑收益)可以换回 1 个底层资产。
<?php
// src/Services/PendleRedeem.php
class PendleRedeem {
/**
* 到期后,用SY赎回本金
* @param PendlePool $pool
* @param float $syAmount
* @return float 赎回的底层资产数量
*/
public static function redeemSy(PendlePool $pool, float $syAmount): float {
// 检查是否到期
if (new DateTime() < $pool->maturityDate) {
throw new Exception("Token not yet matured.");
}
// 检查池子余额
// ... (实际需要检查储备金)
$pool->totalSySupply -= $syAmount;
return $syAmount; // 1:1 赎回
}
/**
* 到期后,用YT索取收益
* @param PendlePool $pool
* @param float $ytAmount
* @return float 应得的收益金额
*/
public static function claimYield(PendlePool $pool, float $ytAmount): float {
if (new DateTime() < $pool->maturityDate) {
throw new Exception("Yield not yet matured.");
}
// 计算收益:总YT代表了总收益,按比例分配
// 前提是池子里有实际的收益储备
$totalYieldReserve = $pool->totalSySupply * $pool->apy * (now - start_date); // 简化
$userShare = $ytAmount / $pool->totalYtSupply;
$earned = $userShare * $totalYieldReserve;
$pool->totalYtSupply -= $ytAmount;
return $earned;
}
}
交易(Swap):实现收益分离的价值发现
Pendle 的精髓在于,YT 可以像普通代币一样交易,所以你需要一个AMM(自动做市商) 逻辑,这不只是简单的加法,而是需要实现一个时间加权的定价模型。
- YT 的价格会随着时间衰减:越接近到期日,YT 代表的未来收益越少,价值越低,到期日 YT 归零。
- SY 的价格会随着时间升水:越接近到期日,SY 越接近于“一个能立刻换回本金加已实现利息”的代币,价值趋近于底层资产。
<?php
// src/Services/PendleAmm.php
class PendleAmm {
/**
* 计算当前YT的市场定价 (使用简单的时间衰减模型)
* @param PendlePool $pool
* @param float $marketYield 市场对未来收益率的预期 (可以视为一个外部输入的参数,或由预言机提供)
* @return float 1个YT在当前时间点的理论价格
*/
public static function getYtPrice(PendlePool $pool, float $marketYield): float {
$now = new DateTime();
$timeToMaturity = $pool->maturityDate->getTimestamp() - $now->getTimestamp();
$secondsInYear = 365.25 * 24 * 3600;
$yearsToMaturity = max(0, $timeToMaturity / $secondsInYear);
// 定价模型:YT价格 = 市场预期的未来收益的现值
// 如果市场预期 APY 是 4%,且还有半年到期,YT 价格 ≈ 0.04 * 0.5 = 0.02
// 实际中考虑折现因子(折现率)和市场供需
$discountedYield = $marketYield * $yearsToMaturity;
// 还要考虑无风险利率等折现,这里简化
return $discountedYield;
}
/**
* 根据AMM池子深度和滑点,计算实际兑换率
* @param float $ytPrice 当前理论价格
* @param float $poolYtSupply 池中YT数量
* @param float $poolSySupply 池中SY数量 (用于计算恒定乘积)
* @param float $swapAmount 用户希望买入/卖出的YT数量
* @return float 实际需要支付的SY数量 (或反之)
*/
public static function swapYtForSy(float $ytPrice, float $poolYtSupply, float $poolSySupply, float $swapAmount): float {
// 使用一个简单的恒定乘积公式: x * y = k
// x = 池中SY数量, y = 池中YT数量 (按价格调整后的)
$k = $poolSySupply * ($poolYtSupply * $ytPrice); // 将YT折算为SY单位
// 用户卖出 $swapAmount 个YT (即增加池中YT,减少池中SY)
$newYtSupply = $poolYtSupply + $swapAmount;
$newSySupply = $k / ($newYtSupply * $ytPrice);
$syUserGets = $poolSySupply - $newSySupply;
return $syUserGets;
}
}
收益分离到底“分离”了什么?
用 PHP 代码的逻辑来理解:
-
分离了风险偏好:
- 持有
SY(代码中的redeemSy()):你是“债主”,到期拿回本金。 - 持有
YT(代码中的swapYtForSy()):你是“股东”,承担未来收益率波动的风险(APY 低于市场预期,YT 价格会跌)。
- 持有
-
分离了时间价值:
YT的价格(getYtPrice())随时间流逝而趋近于 0。SY的价格随时间流逝而趋近于底层资产+已锁定收益。
-
分离了流动性:
你不必因为买了 stETH 就绑定在 Lido 上,你可以卖掉 YT 提前锁定收益,或者买入 YT 加杠杆做多收益率。
实际 Pendle 的 PHP 项目会是什么样?
在现实世界中,一个完整的 Pendle 后端 PHP 项目可能包括:
- 合约交互层 (Contract Layer):使用
web3.php库与以太坊智能合约交互(铸造、赎回、兑换)。 - 数据索引层 (Indexer):读取链上事件,更新 MySQL/Redis 中的 YT 和 SY 的供应量、持仓量、交易对价格。
- 前端 API (REST/GraphQL):提供
GET /pools、POST /mint/sy等接口。 - 利率计算引擎 (Math Engine):上面的
PendleMath,但更复杂,涉及复利、折现因子、隐含收益率计算等。 - 清算与风险管理:对于杠杆头寸,需要监控 YT 价格和保证金率,触发清算。
Pendle 的收益分离,本质上是创建了两个具有不同风险/收益特征的金融工具,让市场参与者可以根据自己的预期和风险承受能力,分别交易资产的“存续价值”和“未来收益流”,PHP 项目在这里扮演的是业务逻辑编排、状态管理和风险计算的角色,而最终的资产确权和交易则发生在链上智能合约中。