质押合约 Stake Contract 源码分析

发布于: 2025-07-18 · 15 min read · 更新于: 2025-07-18
合约开发Web3Solidity

MetaNode质押合约完整项目分析

项目概述

这是一个完整的MetaNode代币质押项目,包含智能合约和前端应用。用户可以通过质押ETH获得MetaNode代币奖励,项目采用流动性挖矿机制,支持多池子质押和灵活的奖励分配策略。

项目结构

1Advanced2-contract-stake/
2├── stake-contract/ # 智能合约
3│ ├── contracts/
4│ │ ├── MetaNodeStake.sol # 主质押合约
5│ │ └── MetaNode.sol # MetaNode代币合约
6│ └── test/ # 测试文件
7└── stake-fe/ # 前端应用
8├── src/
9│ ├── components/ # React组件
10│ ├── pages/ # 页面组件
11│ ├── hooks/ # 自定义Hooks
12│ ├── utils/ # 工具函数
13│ └── assets/ # 静态资源
14└── package.json

智能合约详解

合约架构

1contract MetaNodeStake is
2    Initializable,
3    UUPSUpgradeable,
4    PausableUpgradeable,
5    AccessControlUpgradeable

继承关系说明

  • Initializable: 支持合约升级初始化
  • UUPSUpgradeable: 支持代理升级模式
  • PausableUpgradeable: 支持暂停功能
  • AccessControlUpgradeable: 支持角色权限管理

核心数据结构

Pool结构体

1struct Pool {
2    address stTokenAddress;        // 质押代币地址
3    uint256 poolWeight;            // 池子权重
4    uint256 lastRewardBlock;       // 最后奖励计算区块
5    uint256 accMetaNodePerST;      // 每个质押代币累积的MetaNode奖励
6    uint256 stTokenAmount;         // 池子总质押量
7    uint256 minDepositAmount;      // 最小质押数量
8    uint256 unstakeLockedBlocks;   // 解质押锁定区块数
9}

关键参数详解

  • lastRewardBlock: 记录池子最后一次计算奖励的区块号,用于时间间隔计算, 用户只要质押ETH, USDT.... 等知名代币(具体取决于项目方融资的代币类型), 则按时间一定会获得的奖励
  • accMetaNodePerST: 每个质押代币的累积MetaNode奖励,用于用户奖励计算, 按照用户质押ETH, USDT.... 等知名代币的数量, 获取一定的比例的 MetaNode 这一新代币的奖励, 可以理解为质押时的所产生的利息

User结构体

1struct User {
2    uint256 stAmount;              // 用户质押数量
3    uint256 finishedMetaNode;      // 已完成的MetaNode奖励
4    uint256 pendingMetaNode;       // 待领取的MetaNode奖励
5    UnstakeRequest[] requests;     // 解质押请求列表
6}

UnstakeRequest结构体

1struct UnstakeRequest {
2    uint256 amount;        // 请求解质押数量
3    uint256 unlockBlocks;  // 解锁区块号
4}

奖励计算机制

核心公式

1// 用户待领取奖励计算公式
2pending MetaNode = (user.stAmount * pool.accMetaNodePerST) - user.finishedMetaNode

奖励分配流程

  1. 时间间隔计算: multiplier = block.number - pool.lastRewardBlock
  2. 池子奖励计算: MetaNodeForPool = multiplier * poolWeight / totalPoolWeight
  3. 累积奖励率更新: accMetaNodePerST += MetaNodeForPool * 1e18 / stSupply
  4. 用户奖励计算: 基于用户质押量和累积奖励率

主要函数详解

初始化函数

initialize()

1function initialize(
2    IERC20 _MetaNode,
3    uint256 _startBlock,
4    uint256 _endBlock,
5    uint256 _MetaNodePerBlock
6) public initializer

作用: 合约初始化,设置MetaNode代币地址、开始/结束区块、每区块奖励数量

管理员函数

addPool()

1function addPool(
2    address _stTokenAddress,
3    uint256 _poolWeight,
4    uint256 _minDepositAmount,
5    uint256 _unstakeLockedBlocks,
6    bool _withUpdate
7) public onlyRole(ADMIN_ROLE)

作用: 添加新的质押池,设置质押代币、权重、最小质押量、锁定时间

setMetaNodePerBlock()

1function setMetaNodePerBlock(uint256 _MetaNodePerBlock) public onlyRole(ADMIN_ROLE)

作用: 设置每个区块的MetaNode奖励数量

setPoolWeight()

1function setPoolWeight(uint256 _pid, uint256 _poolWeight, bool _withUpdate) public onlyRole(ADMIN_ROLE)

作用: 设置池子权重,影响奖励分配比例

用户操作函数

depositETH()

1function depositETH() public whenNotPaused() payable

作用: 质押ETH,自动调用_deposit()处理质押逻辑

deposit()

1function deposit(uint256 _pid, uint256 _amount) public whenNotPaused() checkPid(_pid)

作用: 质押ERC20代币,需要先授权合约

unstake()

1function unstake(uint256 _pid, uint256 _amount) public whenNotPaused() checkPid(_pid) whenNotWithdrawPaused()

作用: 申请解质押,立即结算奖励,但资金需要锁定一段时间

withdraw()

1function withdraw(uint256 _pid) public whenNotPaused() checkPid(_pid) whenNotWithdrawPaused()

作用: 提取已解锁的质押资金

claim()

1function claim(uint256 _pid) public whenNotPaused() checkPid(_pid) whenNotClaimPaused()

作用: 领取MetaNode奖励

内部函数

_deposit()

1function _deposit(uint256 _pid, uint256 _amount) internal

作用: 处理质押逻辑的核心函数

  • 更新池子奖励计算
  • 计算并保存用户待领取奖励
  • 更新用户质押量和已完成奖励

updatePool()

1function updatePool(uint256 _pid) public checkPid(_pid)

作用: 更新池子奖励计算

  • 计算时间间隔奖励
  • 更新累积奖励率
  • 更新最后奖励区块

奖励机制详解

时间追踪

  • lastRewardBlock: 记录池子最后奖励计算时间
  • 所有用户共享同一个时间点
  • 确保不会重复计算奖励

奖励分配

  • 按质押量比例分配奖励
  • 用户退出时立即结算
  • 支持多池子不同权重

安全机制

  • 使用SafeMath防止溢出
  • 支持暂停功能
  • 解质押锁定机制防止快速进出

前端应用详解

技术栈

1{
2  "dependencies": {
3    "@rainbow-me/rainbowkit": "^2.2.8",    // 钱包连接
4    "@tanstack/react-query": "^5.55.3",     // 数据查询
5    "framer-motion": "^12.23.5",            // 动画效果
6    "next": "^15.3.3",                      // React框架
7    "react-toastify": "^11.0.5",            // 通知提示
8    "viem": "2.29.2",                       // 以太坊交互
9    "wagmi": "^2.15.6"                      // React Hooks for Ethereum
10  }
11}

项目结构

评论区