惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
Y
Y Combinator Blog
WordPress大学
WordPress大学
L
LangChain Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
About on SuperTechFans
小众软件
小众软件
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
GbyAI
GbyAI
I
InfoQ
The GitHub Blog
The GitHub Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
C
Check Point Blog
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
量子位
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog

博客园 - 程序员李铁牛

纸质档案数字化管理系统研发手记:法院诉讼档案单套制落地案例复盘——从纸质卷宗到电子卷宗 档案数字化管理系统开发手记:人事档案专项审核与数字化的系统支撑——"凡提必审"下的技术要点 档案数字化研发手记:我们的技术栈选择——档案系统前后端选型理由(含一次"炫技"的教训) 社群团购系统开发分享——工程化(下):资金支付测试策略——资金模块 100% 覆盖,其他 60% 就够 社群团购系统类快团团源码开发——工程化(上):一套让 5 人小团队不出事故的开发规范 社群团购类快团团系统开发——RBAC 权限设计源码分析:当一个微信号有 4 种身份时怎么办 社群团购系统类快团团模式开发——微信小程序登录:code2Session 之后还有 5 件事要做 数字档案管理系统化研发手记:医院病历档案数字化——合规、病案首页 OCR 与调阅提速 数字档案系统研发手记:批量扫描任务调度——TWAIN/SANE 采集驱动的封装实践 档案数字化系统研发源码手记:置信度过滤——把 97% 识别率变成真正可交付的成果 档案数字化开发实例手记:盖章遮挡文字识别恢复 景区运营预约系统开发:景区会员体系怎么搭?3级会员模型+积分玩法 景区门票预约系统全渠道平台库存数据同步技术处理方式 系统宕机了怎么办?景区票务系统应急预案模板 景区门票预约系统开发:接入AI预测客流设计思路分析 景区预约系统开发总结:门票分时预约设计原理和落地方法 设备运维管理系统开发实战:用规则引擎实现可配置的设备告警策略自研轻量引擎 vs Drools 落地对比 设备维修保养系统预测性维护不用深度学习?设备健康度评分的务实实现方案 档案数字化管理系统研发手记:档案权限模型——全宗-门类-案卷-文件四级控制的设计与实践 档案管理信息化系统研发手记:数字水印方案对比——可见水印 vs 盲水印(档案借阅防泄露) 景区票务系统开发实例分析:上云还是本地部署?6个维度判断 档案数字化系统源码研发手记:老旧档案去污点——中值滤波与 inpainting 效果对比 一物一码防伪溯源系统开发全栈源码串联一次扫码的完整链路追踪代码走读 景区门票预约系统票务系统的6个核心模块 景区上线门票预约系统的5个常见翻车点 景区门票预约系统之人脸识别 vs 身份证核验 vs 扫码入园,哪种最适合你? 景区门票预约系统开发深度解析之定价策略功能设计 景区门票预约系统开发深度解析 设备管理系统开发核心功能讲解 卷轴模式逻辑设计深度讲解
MAXFI系统开发源码和核心智能合约分享
程序员李铁牛 · 2025-11-26 · via 博客园 - 程序员李铁牛

第一章:合约系统架构总览​​

MAXFI的智能合约系统将采用模块化设计,各合约职责分离,通过接口相互调用,以提高安全性、可维护性和可升级性。整个系统架构如下所示:

image

  • ​​MaxFiMain合约​​:用户主要交互的合约。它负责将函数调用委托给相应的模块合约,并管理各模块间的地址引用。
  • ​​MAX代币合约 (MAXToken)​​:标准的ERC-20代币实现,负责MAX代币的转账、余额查询等基本功能。
  • ​​创世节点销售合约 (NodeSale)​​:处理创世节点的购买逻辑,包括限额检查、支付接收和节点资格分配。
  • ​​质押收益合约 (StakingPool)​​:核心业务逻辑合约,管理用户的双仓(质押仓、创世仓),计算并发放收益。
  • ​​推荐奖励合约 (ReferralSystem)​​:记录推荐关系,并在成功购买节点时分配推荐奖励。

第二章:合约详细实现与代码分析​​

以下将分节详细描述每个合约的关键代码结构。我们将使用Solidity语言(0.8.x及以上版本,强调安全性)进行编写。

​​2.1 MAX代币合约 (MAXToken.sol)​​

这是一个标准的ERC-20合约,但增加了铸造(Mint)功能和权限管理,用于项目初始发行。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MAXToken is ERC20, Ownable {
    // 代币总供应量:3亿枚,但考虑到小数位(默认18位),需要乘以10^18
    uint256 public constant MAX_SUPPLY = 300000000 * 10**18;

    // 分配地址:在实际部署时需要设置
    address public treasuryWallet; // 国库地址
    address public incentivePoolWallet; // 激励池地址
    address public managementPoolWallet; // 管理池地址
    address public otherWallet; // 其他用途地址

    constructor(
        address _treasury,
        address _incentivePool,
        address _managementPool,
        address _other
    ) ERC20("MAXFI Token", "MAX") {
        require(_treasury != address(0) && _incentivePool != address(0), "Invalid address");
        treasuryWallet = _treasury;
        incentivePoolWallet = _incentivePool;
        managementPoolWallet = _managementPool;
        otherWallet = _other;

        // 根据图片中的分配方案一次性铸造全部代币
        _mint(treasuryWallet, 36950000 * 10**18);       // 国库
        _mint(incentivePoolWallet, 132360000 * 10**18); // 激励池
        _mint(managementPoolWallet, 71100000 * 10**18); // 管理池
        _mint(otherWallet, 59700000 * 10**18);          // 其他 (注意:97,700,000 - 37,950,000? 需明确分配)
        // 确保总量为3亿
        assert(totalSupply() == MAX_SUPPLY);
    }

    // 可增加交易税等功能,此处为简化版标准代币
}

2.2 创世节点销售合约 (NodeSale.sol)​​

此合约是用户购买创世节点的入口,包含核心的业务规则校验。

pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./MAXToken.sol";
import "./IStakingPool.sol";
import "./IReferralSystem.sol";

contract NodeSale is Ownable {
    IERC20 public usdtToken; // 用于支付的稳定币合约地址(例如USDT)
    IStakingPool public stakingPool;
    IReferralSystem public referralSystem;

    uint256 public constant NODE_PRICE = 100 * 10**6; // 100 USDT (假设USDT有6位小数)
    uint256 public constant MAX_NODES = 2000;
    uint256 public totalNodesSold;

    // 记录地址是否已购买节点
    mapping(address => bool) public isNodeHolder;
    // 记录已购买节点的地址列表
    address[] public nodeHolders;

    event NodePurchased(address indexed buyer, address indexed referrer, uint256 nodeId);

    constructor(address _usdtAddress, address _stakingPool, address _referralSystem) {
        usdtToken = IERC20(_usdtAddress);
        stakingPool = IStakingPool(_stakingPool);
        referralSystem = IReferralSystem(_referralSystem);
    }

    /**
     * @dev 用户购买创世节点的主要函数
     * @param _referrer 推荐人地址(如果无可为0x0)
     */
    function purchaseNode(address _referrer) external {
        require(totalNodesSold < MAX_NODES, "All genesis nodes sold out");
        require(!isNodeHolder[msg.sender], "Already purchased a node");
        require(msg.sender != _referrer, "Cannot refer yourself");

        // 检查用户是否已授权足够的USDT给本合约
        require(usdtToken.allowance(msg.sender, address(this)) >= NODE_PRICE, "Insufficient USDT allowance");
        // 将USDT从用户转账到本合约(实际项目中,通常转入一个特定的财政钱包)
        require(usdtToken.transferFrom(msg.sender, address(this), NODE_PRICE), "USDT transfer failed");

        // 更新状态
        totalNodesSold++;
        isNodeHolder[msg.sender] = true;
        nodeHolders.push(msg.sender);
        uint256 nodeId = totalNodesSold; // 节点ID从1开始

        // 调用质押合约,为用户创建双仓(100U质押仓 + 100U创世仓)
        stakingPool.createGenesisStake(msg.sender, NODE_PRICE); // 传递100 USDT的价值

        // 处理推荐关系与奖励分配
        if (_referrer != address(0) && isNodeHolder[_referrer]) {
            referralSystem.handleReferral(_referrer, msg.sender, NODE_PRICE);
        }

        emit NodePurchased(msg.sender, _referrer, nodeId);
    }

    // 所有者函数:用于提取合约中积累的USDT
    function withdrawUSDT(address _to) external onlyOwner {
        uint256 balance = usdtToken.balanceOf(address(this));
        require(balance > 0, "No USDT to withdraw");
        require(usdtToken.transfer(_to, balance));
    }
}

2.3 质押收益合约 (StakingPool.sol)​​

这是系统中最复杂的合约,负责管理仓位、计算收益和处理本金取回。

pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract StakingPool is Ownable, ReentrancyGuard {
    IERC20 public maxToken;

    // 基础收益率(每日0.6%,以分子形式表示,分母为10000,即60/10000=0.6%)
    uint256 public constant BASE_RATE = 60;
    uint256 public constant RATE_DENOMINATOR = 10000;
    uint256 public constant RATE_INCREASE_INTERVAL = 2 days; // 48小时
    uint256 public constant RATE_INCREASE_AMOUNT = 10; // 每48小时增加0.1%

    uint256 public systemLaunchTime;
    uint256 public currentGlobalRate = BASE_RATE;

    struct Stake {
        uint256 stakingAmount;    // 质押仓位金额(100 USDT等值的MAX)
        uint256 genesisAmount;    // 创世仓位金额(100 USDT等值的MAX)
        uint256 lastUpdateTime;   // 最后一次更新收益的时间戳
        bool isActive;            // 节点资格是否有效(取回本金后失效)
    }

    mapping(address => Stake) public stakes;

    event Staked(address indexed user, uint256 stakingAmount, uint256 genesisAmount);
    event RewardClaimed(address indexed user, uint256 reward);
    event Unstaked(address indexed user, uint256 amount);

    modifier onlyAfterLaunch {
        require(systemLaunchTime != 0 && block.timestamp >= systemLaunchTime, "System not launched");
        _;
    }

    constructor(address _maxTokenAddress) {
        maxToken = IERC20(_maxTokenAddress);
    }

    // 由NodeSale合约调用的函数,为用户初始化质押
    function createGenesisStake(address _user, uint256 _usdtAmount) external onlyOwner {
        require(_usdtAmount == 100 * 10**6, "Invalid stake amount"); // 必须为100USDT
        require(stakes[_user].stakingAmount == 0, "Stake already exists");

        // 假设1USDT = 1 MAX(初始定价),将USDT价值映射为MAX代币数量进行记录
        // 实际项目中,这里可能需要一个预言机来确定USDT/MAX的汇率,此处简化处理
        uint256 stakeAmountInMAX = _usdtAmount; // 简化:1:1锚定

        stakes[_user] = Stake({
            stakingAmount: stakeAmountInMAX,
            genesisAmount: stakeAmountInMAX, // 赠送等额的创世仓位
            lastUpdateTime: block.timestamp,
            isActive: true
        });

        // 更新全局收益率(基于系统运行时间)
        _updateGlobalRate();
        emit Staked(_user, stakeAmountInMAX, stakeAmountInMAX);
    }

    /**
     * @dev 计算用户应得的累计收益(包括质押仓和创世仓)
     */
    function calculateRewards(address _user) public view returns (uint256) {
        Stake memory userStake = stakes[_user];
        if (userStake.stakingAmount == 0 || !userStake.isActive) return 0;

        // 计算从上次更新到现在的时间段数
        uint256 timeElapsed = block.timestamp - userStake.lastUpdateTime;
        uint256 intervals = timeElapsed / RATE_INCREASE_INTERVAL;

        // 简化收益计算:使用平均收益率
        // 总仓位 = 质押仓 + 创世仓
        uint256 totalStakeAmount = userStake.stakingAmount + userStake.genesisAmount;
        // 平均日化收益率 = 当前全局收益率
        // 收益 = 总仓位 * 平均日化收益率 * 经过的天数
        // 注意:这是一个简化的线性模型,实际复利计算更复杂,需要在每个间隔内单独计算
        uint256 averageRate = currentGlobalRate;
        uint256 daysStaked = timeElapsed / 1 days;
        uint256 reward = (totalStakeAmount * averageRate * daysStaked) / RATE_DENOMINATOR;

        return reward;
    }

    /**
     * @dev 用户提取已产生的收益
     */
    function claimRewards() external nonReentrant onlyAfterLaunch {
        uint256 reward = calculateRewards(msg.sender);
        require(reward > 0, "No rewards to claim");

        // 更新用户的最后结算时间
        stakes[msg.sender].lastUpdateTime = block.timestamp;
        _updateGlobalRate();

        // 将收益代币转账给用户
        require(maxToken.transfer(msg.sender, reward), "Reward transfer failed");
        emit RewardClaimed(msg.sender, reward);
    }

    /**
     * @dev 用户取回质押本金(30天后),并丧失节点资格
     */
    function unstake() external nonReentrant onlyAfterLaunch {
        Stake storage userStake = stakes[msg.sender];
        require(userStake.isActive, "No active stake or already unstaked");
        require(block.timestamp >= systemLaunchTime + 30 days, "Cannot unstake before 30 days");

        // 结算所有未领取的收益
        uint256 reward = calculateRewards(msg.sender);
        if (reward > 0) {
            require(maxToken.transfer(msg.sender, reward), "Reward transfer failed");
        }

        uint256 amountToReturn = userStake.stakingAmount; // 只能取回质押的100U等值MAX
        // 销毁创世仓位(不退还)
        userStake.stakingAmount = 0;
        userStake.genesisAmount = 0;
        userStake.isActive = false; // 标记节点资格失效

        // 退还本金
        require(maxToken.transfer(msg.sender, amountToReturn), "Return of stake failed");
        emit Unstaked(msg.sender, amountToReturn);
    }

    /**
     * @dev 内部函数,更新全局收益率
     */
    function _updateGlobalRate() internal {
        if (systemLaunchTime == 0) {
            systemLaunchTime = block.timestamp; // 在第一次交互时启动系统
            return;
        }
        uint256 timeElapsed = block.timestamp - systemLaunchTime;
        uint256 intervals = timeElapsed / RATE_INCREASE_INTERVAL;
        currentGlobalRate = BASE_RATE + (intervals * RATE_INCREASE_AMOUNT);
    }

    // 所有者函数:设置启动时间、处理额外奖励(每日1MAX)等。
    function setLaunchTime(uint256 _launchTime) external onlyOwner {
        systemLaunchTime = _launchTime;
    }
}

2.4 推荐奖励合约 (ReferralSystem.sol)​​

此合约管理多级推荐关系和在购买节点时分配奖励。

pragma solidity ^0.8.19;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract ReferralSystem is Ownable {
    IERC20 public usdtToken;
    IERC20 public maxToken;

    // 总奖励池(每个节点35 USDT)
    uint256 public constant REF_POOL_PER_NODE = 35 * 10**6;

    // 推荐奖励比例(1层20%,2层10%,3层5%)
    uint256[] public refRates = [2000, 1000, 500]; // 分母为10000,即20%=2000/10000
    uint256 public constant RATE_DENOMINATOR = 10000;

    // 直推额外MAX奖励
    uint256 public constant DIRECT_REF_MAX_REWARD = 2 * 10**18; // 2 MAX
    uint256 public constant DIRECT_REF_MAX_CAP = 600 * 10**18; // 600 MAX上限

    // 记录用户的推荐人
    mapping(address => address) public referrerOf;
    // 记录用户已获得的直推MAX奖励总额
    mapping(address => uint256) public directRefMaxEarned;

    event ReferralRecorded(address indexed referrer, address indexed referee, uint256 level, uint256 rewardUSDT, uint256 rewardMAX);

    constructor(address _usdtAddress, address _maxAddress) {
        usdtToken = IERC20(_usdtAddress);
        maxToken = IERC20(_maxAddress);
    }

    /**
     * @dev 由NodeSale合约调用,处理推荐奖励分配
     */
    function handleReferral(address _referrer, address _referee, uint256 _nodePrice) external onlyOwner {
        require(_referrer != address(0) && _referee != address(0), "Invalid address");
        referrerOf[_referee] = _referrer;

        address current = _referrer;
        uint256 totalUSDTDistributed = 0;

        // 遍历1-3层推荐人
        for (uint256 i = 0; i < refRates.length; i++) {
            if (current == address(0)) break; // 没有更上层的推荐人

            uint256 rewardUSDT = (REF_POOL_PER_NODE * refRates[i]) / RATE_DENOMINATOR;
            totalUSDTDistributed += rewardUSDT;

            // 分配USDT奖励(需要确保本合约有足够的USDT余额)
            if (rewardUSDT > 0 && usdtToken.balanceOf(address(this)) >= rewardUSDT) {
                require(usdtToken.transfer(current, rewardUSDT), "USDT referral transfer failed");
            }

            // 如果是第一层(直推),额外分配MAX奖励
            if (i == 0) {
                if (directRefMaxEarned[current] + DIRECT_REF_MAX_REWARD <= DIRECT_REF_MAX_CAP) {
                    if (maxToken.balanceOf(address(this)) >= DIRECT_REF_MAX_REWARD) {
                        require(maxToken.transfer(current, DIRECT_REF_MAX_REWARD), "MAX referral transfer failed");
                        directRefMaxEarned[current] += DIRECT_REF_MAX_REWARD;
                    }
                }
            }

            emit ReferralRecorded(current, _referee, i+1, rewardUSDT, i == 0 ? DIRECT_REF_MAX_REWARD : 0);

            // 移动到上一层推荐人
            current = referrerOf[current];
        }
    }
}

第三章:关键特性与安全考量​​

  • ​​使用OpenZeppelin库​​:合约继承自OwnableReentrancyGuard,并使用ERC20标准,这些都经过广泛测试,能有效防止常见漏洞。
  • ​​重入攻击防护​​:在关键函数(如claimRewardsunstake)中使用nonReentrant修饰符。
  • ​​整数溢出防护​​:Solidity 0.8.x内置了整数溢出检查。
  • ​​访问控制​​:关键的管理函数(如提取资金、设置启动时间)由onlyOwner修饰,确保只有部署者可以调用。
  • ​​简化与假设​​:上述代码为演示核心逻辑的简化版。实际生产环境需要考虑:
    • ​​汇率问题​​:USDT与MAX代币的汇率需要通过​​去中心化预言机(如Chainlink)​​ 动态获取。
    • ​​精确收益计算​​:当前的收益计算是简化模型。精确的复利计算需要记录每个利率变化周期的份额,或采用更复杂的算法。
    • ​​AI超燃协议​​:实现动态收益调整需要将链下AI计算的结果通过预言机输入到合约中,修改calculateRewards函数。
    • ​​Gas优化​​:对于循环和映射操作需进行优化,避免达到区块Gas上限。
    • ​​全面的单元测试和第三方审计​​:这是DeFi项目安全上线的必要条件。