前言随着以太坊生态进入“可验证计算”时代,再质押(Restaking)已成为安全共享的核心机制。而在其之上诞生的液态再质押(LiquidRestaking,LRT),则通过解决资产流动性与收益效率的矛盾,成为了2026年去中心化金融最关键的基础设施。一、什么是液态再质押(LRT
随着以太坊生态进入“可验证计算”时代,再质押(Restaking)已成为安全共享的核心机制。而在其之上诞生的液态再质押(Liquid Restaking, LRT) ,则通过解决资产流动性与收益效率的矛盾,成为了 2026 年去中心化金融最关键的基础设施。
一、 什么是液态再质押 (LRT)?
传统的再质押(如直接在 EigenLayer 质押)会将资产(如 stETH)锁定在智能合约中,用户在获得额外收益的同时,也失去了资产的流动性。
LRT 的本质是:
用户将 LST 或原始代币存入 LRT 协议,协议代表用户在再质押层进行操作,并向用户发放等比例的 LRT 代币(如 LRT-ETH) 。该代币不仅代表了底层资产的所有权,还承载了质押奖励、再质押奖励(AVS 收益)及流动性。
一个完整的 LRT 系统并非单一合约,而是由多个功能解耦的组件构成的生态集群:
基于 ERC20 标准,它是系统对外的凭证。
这是用户交互的核心入口。
解决质押协议“长延迟”痛点的关键。
在最新的 Solidity 0.8.24+ 开发环境下,LRT 合约大量引入了 TSTORE 指令。
通过 Chainlink CCIP 等互操作协议,LRT 已经突破了以太坊主网的限制。
LRT 的价格不再固定,而是基于 资产净值 (NAV) 动态跳动:
$$LRT_Price=\frac{合约闲置资产+策略内份额价值+待领取收益}{LRT总供应量}$$
<br/>这要求协议必须集成高性能的预言机(如 RedStone 或 Chainlink)来实时喂价,确保铸造和销毁过程的公平性。
LRT 协议在放大收益的同时,也放大了 Slash(惩罚)风险。如果底层的 AVS(主动验证服务)发生节点违规,资产将被扣除。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
contract LRTToken is ERC20, ERC20Permit, AccessControl { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
constructor() ERC20("Liquid Restaking Token", "LRT") ERC20Permit("LRT") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function burn(address from, uint256 amount) external onlyRole(BURNER_ROLE) {
_burn(from, amount);
}
}
* **LRTDepositPool.sol (存款与策略中心)**
```js
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "./LRTToken.sol";
interface IEigenStrategyManager {
function depositIntoStrategy(address strategy, address token, uint256 amount) external returns (uint256);
}
contract LRTDepositPool is AccessControl, ReentrancyGuardTransient {
using SafeERC20 for IERC20;
LRTToken public immutable lrtToken;
address public immutable strategyManager; // EigenLayer 地址
mapping(address => address) public assetToStrategy;
mapping(address => bool) public isSupportedAsset;
constructor(address _lrtToken, address _strategyManager) {
lrtToken = LRTToken(_lrtToken);
strategyManager = _strategyManager;
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
}
// 1. 用户存款
function deposit(address asset, uint256 amount) external nonReentrant {
require(isSupportedAsset[asset], "Unsupported");
// 计算汇率(此处简化,实际应接入 Oracle)
uint256 lrtAmount = amount;
IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
lrtToken.mint(msg.sender, lrtAmount);
}
// 2. 将资金投入 EigenLayer
// function invest(address asset, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
// address strategy = assetToStrategy[asset];
// IERC20(asset).forceApprove(strategyManager, amount);
// IEigenStrategyManager(strategyManager).depositIntoStrategy(strategy, asset, amount);
// }
function invest(address asset, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) {
address strategy = assetToStrategy[asset];
IERC20(asset).forceApprove(strategyManager, amount);
// 增加一个简单的检查或确保 strategyManager 是正确的合约
try IEigenStrategyManager(strategyManager).depositIntoStrategy(strategy, asset, amount) {
// success
} catch {
// 在测试环境下,如果 Manager 是 Mock 的且没实现该函数,可以捕获它防止整体 Revert
revert("EigenLayer Call Failed - Check StrategyManager Address");
}
}
function setAsset(address asset, address strategy) external onlyRole(DEFAULT_ADMIN_ROLE) {
isSupportedAsset[asset] = true;
assetToStrategy[asset] = strategy;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;import "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./LRTToken.sol";
contract LRTWithdrawalQueue is ReentrancyGuardTransient { using SafeERC20 for IERC20;
struct Request {
address user;
address asset;
uint256 amount;
uint256 unlockTime;
bool claimed;
}
LRTToken public immutable lrtToken;
uint256 public constant LOCK_PERIOD = 7 days;
uint256 public nextId;
mapping(uint256 => Request) public requests;
constructor(address _lrtToken) {
lrtToken = LRTToken(_lrtToken);
}
function requestWithdraw(address asset, uint256 lrtAmount) external {
// 计算底层资产数量(简化)
uint256 assetAmount = lrtAmount;
lrtToken.burn(msg.sender, lrtAmount);
requests[nextId++] = Request({
user: msg.sender,
asset: asset,
amount: assetAmount,
unlockTime: block.timestamp + LOCK_PERIOD,
claimed: false
});
}
function claim(uint256 id) external nonReentrant {
Request storage req = requests[id];
require(block.timestamp >= req.unlockTime, "Locked");
require(msg.sender == req.user, "Not owner");
require(!req.claimed, "Claimed");
req.claimed = true;
IERC20(req.asset).safeTransfer(msg.sender, req.amount);
}
}
### 测试脚本
#### 测试用例:LRT 协议完整集成测试套件
1. **质押与铸造:用户存入 stETH 应 1:1 获得 LRT**
2. **权限拦截:非授权账户无法直接铸造或销毁代币**
3. **提现队列:申请提现应正确销毁 LRT 并进入 7 天锁定期**
4. **提现限制:冷却期内领取应失败**
5. **管理员控制:动态调整资产支持列表**
6. **角色转移:DEFAULT_ADMIN 权限移交测试**
```js
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { parseEther, getAddress, zeroAddress } from "viem";
import { network } from "hardhat";
describe("LRT Protocol Full Integration Test Suite", function () {
async function deployFixture() {
const { viem } = await (network as any).connect();
const [owner, user, otherAccount] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
// 1. 部署合约
const lrtToken = await viem.deployContract("LRTToken");
const mockStETH = await viem.deployContract("BoykaYuriToken", [owner.account.address, owner.account.address]);
const depositPool = await viem.deployContract("LRTDepositPool", [lrtToken.address, owner.account.address]);
const withdrawalQueue = await viem.deployContract("LRTWithdrawalQueue", [lrtToken.address]);
// 2. 角色常量
const MINTER_ROLE = await lrtToken.read.MINTER_ROLE();
const BURNER_ROLE = await lrtToken.read.BURNER_ROLE();
const DEFAULT_ADMIN = await lrtToken.read.DEFAULT_ADMIN_ROLE();
// 3. 授权
await lrtToken.write.grantRole([MINTER_ROLE, depositPool.address]);
await lrtToken.write.grantRole([BURNER_ROLE, withdrawalQueue.address]);
await depositPool.write.setAsset([mockStETH.address, owner.account.address]);
return {
lrtToken, depositPool, withdrawalQueue, mockStETH,
owner, user, otherAccount, publicClient,
MINTER_ROLE, BURNER_ROLE, DEFAULT_ADMIN
};
}
it("1. 质押与铸造:用户存入 stETH 应 1:1 获得 LRT", async function () {
const { depositPool, lrtToken, mockStETH, user } = await deployFixture();
const amount = parseEther("10");
await mockStETH.write.transfer([user.account.address, amount]);
await mockStETH.write.approve([depositPool.address, amount], { account: user.account });
await depositPool.write.deposit([mockStETH.address, amount], { account: user.account });
const balance = await lrtToken.read.balanceOf([user.account.address]);
assert.equal(balance, amount, "LRT 铸造数量不匹配");
});
it("2. 权限拦截:非授权账户无法直接铸造或销毁代币", async function () {
const { lrtToken, user } = await deployFixture();
// 尝试越权铸造
await assert.rejects(
async () => {
await lrtToken.write.mint([user.account.address, 1n], { account: user.account });
},
/AccessControl/,
"普通用户不应拥有 MINTER 权限"
);
});
it("3. 提现队列:申请提现应正确销毁 LRT 并进入 7 天锁定期", async function () {
const { withdrawalQueue, lrtToken, user, owner, mockStETH } = await deployFixture();
const amount = parseEther("5");
// 1. 模拟用户持有 LRT (先 Mint 给用户)
const MINTER = await lrtToken.read.MINTER_ROLE();
await lrtToken.write.grantRole([MINTER, owner.account.address]);
await lrtToken.write.mint([user.account.address, amount]);
// 2. 申请提现 (假设提现 stETH)
await withdrawalQueue.write.requestWithdraw([mockStETH.address, amount], { account: user.account });
// 3. 验证 LRT 是否销毁
const balanceAfter = await lrtToken.read.balanceOf([user.account.address]);
assert.equal(balanceAfter, 0n, "LRT 未能成功销毁");
// 4. 验证队列记录
// 注意:Viem 返回 struct 时,如果是数组形式,user 通常是第一个元素 [0]
// 如果是命名对象,则是 req.user
const req = await withdrawalQueue.read.requests([0n]);
// 修复:确保传入的是地址字符串
const requesterAddress = Array.isArray(req) ? req[0] : req.user;
const unlockTime = Array.isArray(req) ? req[3] : req.unlockTime;
assert.equal(
getAddress(requesterAddress as string),
getAddress(user.account.address),
"申请人地址不匹配"
);
assert.ok(unlockTime > 0n, "解锁时间未设置");
});
it("4. 提现限制:冷却期内领取应失败", async function () {
const { withdrawalQueue, user } = await deployFixture();
// 假设 ID 0 已在上一测试或本测试准备中创建
try {
await withdrawalQueue.write.claim([0n], { account: user.account });
assert.fail("应在锁定期间 revert");
} catch (e: any) {
// 由于 Cancun EVM 兼容性,这里捕获 revert 信号即可
assert.ok(true);
}
});
it("5. 管理员控制:动态调整资产支持列表", async function () {
const { depositPool, otherAccount } = await deployFixture();
const newAsset = "0x1234567890123456789012345678901234567890";
// 非管理员尝试设置资产
await assert.rejects(
async () => {
await depositPool.write.setAsset([newAsset, zeroAddress], { account: otherAccount.account });
},
/AccessControl/
);
// 管理员设置资产
await depositPool.write.setAsset([newAsset, zeroAddress]);
const isSupported = await depositPool.read.isSupportedAsset([newAsset]);
assert.equal(isSupported, true, "管理员应能成功设置支持资产");
});
it("6. 角色转移:DEFAULT_ADMIN 权限移交测试", async function () {
const { lrtToken, owner, otherAccount, DEFAULT_ADMIN } = await deployFixture();
// 1. 授予新管理员权限
await lrtToken.write.grantRole([DEFAULT_ADMIN, otherAccount.account.address]);
// 2. 旧管理员放弃权限
await lrtToken.write.renounceRole([DEFAULT_ADMIN, owner.account.address]);
// 3. 验证旧管理员无法再授权 MINTER
await assert.rejects(
async () => {
await lrtToken.write.grantRole([await lrtToken.read.MINTER_ROLE(), owner.account.address]);
},
/AccessControl/
);
// 4. 验证新管理员可以操作
const tx = await lrtToken.write.grantRole([await lrtToken.read.MINTER_ROLE(), owner.account.address], { account: otherAccount.account });
assert.ok(tx);
});
});
// scripts/deploy.js
import { network, artifacts } from "hardhat";
async function main() {
// 连接网络
const { viem } = await network.connect({ network: network.name });//指定网络进行链接
// 获取客户端
const [deployer] = await viem.getWalletClients();
const publicClient = await viem.getPublicClient();
const deployerAddress = deployer.account.address;
console.log("部署者的地址:", deployerAddress);
// 加载合约
const BoykaYuriTokenArtifact = await artifacts.readArtifact("BoykaYuriToken");
const LRTTokenArtifact = await artifacts.readArtifact("LRTToken");
// 部署(构造函数参数:recipient, initialOwner)
const BoykaYuriTokenHash = await deployer.deployContract({
abi: BoykaYuriTokenArtifact.abi,//获取abi
bytecode: BoykaYuriTokenArtifact.bytecode,//硬编码
args: [deployerAddress,deployerAddress],//部署者地址,初始所有者地址
});
const BoykaYuriTokenReceipt = await publicClient.waitForTransactionReceipt({ hash: BoykaYuriTokenHash });
console.log("代币合约地址:", BoykaYuriTokenReceipt.contractAddress);
//
const LRTTokenHash = await deployer.deployContract({
abi: LRTTokenArtifact.abi,//获取abi
bytecode: LRTTokenArtifact.bytecode,//硬编码
args: [],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const LRTTokenReceipt = await publicClient.waitForTransactionReceipt({ hash: LRTTokenHash });
console.log("LRTToken合约地址:", LRTTokenReceipt.contractAddress);
const LRTDepositPoolArtifact = await artifacts.readArtifact("LRTDepositPool");
const LRTDepositPoolHash = await deployer.deployContract({
abi: LRTDepositPoolArtifact.abi,//获取abi
bytecode: LRTDepositPoolArtifact.bytecode,//硬编码
args: [LRTTokenReceipt.contractAddress,deployerAddress],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const LRTDepositPoolReceipt = await publicClient.waitForTransactionReceipt({ hash: LRTDepositPoolHash });
console.log("LRTDepositPool合约地址:", LRTDepositPoolReceipt.contractAddress);
const LRTWithdrawalQueueArtifact = await artifacts.readArtifact("LRTWithdrawalQueue");
const LRTWithdrawalQueueHash = await deployer.deployContract({
abi: LRTWithdrawalQueueArtifact.abi,//获取abi
bytecode: LRTWithdrawalQueueArtifact.bytecode,//硬编码
args: [LRTTokenReceipt.contractAddress],//部署者地址,初始所有者地址
});
// 等待确认并打印地址
const LRTWithdrawalQueueReceipt = await publicClient.waitForTransactionReceipt({ hash: LRTWithdrawalQueueHash });
console.log("LRTWithdrawalQueue合约地址:", LRTWithdrawalQueueReceipt.contractAddress);
}
main().catch(console.error);
液态再质押(LRT)不仅是 DeFi 收益率的杠杆,更是以太坊安全共识向外输出的管道。通过模块化的合约设计(代币+存款池+提现队列),LRT 在保证安全性的前提下,真正实现了“一鱼多吃”的资产效率最大化。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!