

























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

以下将分节详细描述每个合约的关键代码结构。我们将使用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]; } } }
Ownable,ReentrancyGuard,并使用ERC20标准,这些都经过广泛测试,能有效防止常见漏洞。claimRewards, unstake)中使用nonReentrant修饰符。onlyOwner修饰,确保只有部署者可以调用。calculateRewards函数。此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。