Skip to content

代币分红池系统

1. 系统概述

代币分红池系统是一个基于 Solidity 实现的去中心化分红管理平台,支持多种代币的分红发放和收益分配。系统实现了灵活的分红策略和完善的收益计算机制。

1.1 主要特点

  • 多币种分红:支持多种代币分红
  • 实时计算:动态收益计算
  • 按比例分配:基于份额分配
  • 自动分发:自动化分红发放
  • 历史记录:完整的分红记录

2. 合约实现

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

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

/**
 * @title TokenDividendPool
 * @dev 代币分红池合约
 */
contract TokenDividendPool is Ownable, ReentrancyGuard {
    using SafeMath for uint256;

    // 分红池信息
    struct Pool {
        IERC20 token;              // 分红代币
        uint256 totalShares;       // 总份额
        uint256 totalReleased;     // 总发放量
        uint256 lastUpdateTime;    // 最后更新时间
        bool isActive;             // 是否激活
    }

    // 用户份额信息
    struct ShareInfo {
        uint256 shares;            // 持有份额
        uint256 released;          // 已领取量
        uint256 lastClaimTime;     // 上次领取时间
    }

    // 分红记录
    struct DividendRecord {
        uint256 amount;            // 分红数量
        uint256 timestamp;         // 分红时间
        uint256 totalShares;       // 当时总份额
    }

    // 状态变量
    mapping(uint256 => Pool) public pools;                      // 分红池信息
    mapping(uint256 => mapping(address => ShareInfo)) public shareInfo;  // 用户份额信息
    mapping(uint256 => DividendRecord[]) public dividendRecords;  // 分红记录
    uint256 public poolCount;                                   // 分红池数量
    uint256 public minClaimInterval;                           // 最小领取间隔
    bool public paused;                                        // 暂停状态

    // 常量
    uint256 public constant PRECISION = 1e18;                  // 精度
    uint256 public constant MIN_SHARES = 1e6;                  // 最小份额

    // 事件
    event PoolCreated(uint256 indexed poolId, address token);
    event SharesUpdated(uint256 indexed poolId, address indexed user, uint256 shares);
    event DividendReleased(uint256 indexed poolId, address indexed user, uint256 amount);
    event DividendAdded(uint256 indexed poolId, uint256 amount);
    event PoolStatusChanged(uint256 indexed poolId, bool isActive);

    /**
     * @dev 构造函数
     */
    constructor(uint256 _minClaimInterval) {
        minClaimInterval = _minClaimInterval;
    }

    /**
     * @dev 创建分红池
     */
    function createPool(IERC20 _token) external onlyOwner {
        pools[poolCount] = Pool({
            token: _token,
            totalShares: 0,
            totalReleased: 0,
            lastUpdateTime: block.timestamp,
            isActive: true
        });

        emit PoolCreated(poolCount, address(_token));
        poolCount = poolCount.add(1);
    }

    /**
     * @dev 更新份额
     */
    function updateShares(uint256 poolId, address user, uint256 shares) external onlyOwner {
        require(poolId < poolCount, "Invalid pool ID");
        require(shares >= MIN_SHARES || shares == 0, "Invalid shares");

        Pool storage pool = pools[poolId];
        require(pool.isActive, "Pool not active");

        ShareInfo storage info = shareInfo[poolId][user];
        
        // 更新总份额
        pool.totalShares = pool.totalShares.sub(info.shares).add(shares);
        info.shares = shares;

        emit SharesUpdated(poolId, user, shares);
    }

    /**
     * @dev 添加分红
     */
    function addDividend(uint256 poolId, uint256 amount) external nonReentrant {
        require(poolId < poolCount, "Invalid pool ID");
        require(amount > 0, "Amount must be greater than 0");

        Pool storage pool = pools[poolId];
        require(pool.isActive, "Pool not active");
        require(pool.totalShares > 0, "No shares");

        // 转入分红代币
        pool.token.transferFrom(msg.sender, address(this), amount);

        // 记录分红
        dividendRecords[poolId].push(DividendRecord({
            amount: amount,
            timestamp: block.timestamp,
            totalShares: pool.totalShares
        }));

        emit DividendAdded(poolId, amount);
    }

    /**
     * @dev 领取分红
     */
    function claimDividend(uint256 poolId) external nonReentrant {
        require(poolId < poolCount, "Invalid pool ID");
        require(!paused, "System paused");

        Pool storage pool = pools[poolId];
        ShareInfo storage info = shareInfo[poolId][msg.sender];
        require(info.shares > 0, "No shares");
        require(
            block.timestamp >= info.lastClaimTime.add(minClaimInterval),
            "Too frequent"
        );

        // 计算可领取数量
        uint256 claimable = getClaimableDividend(poolId, msg.sender);
        require(claimable > 0, "Nothing to claim");

        // 更新状态
        info.released = info.released.add(claimable);
        info.lastClaimTime = block.timestamp;
        pool.totalReleased = pool.totalReleased.add(claimable);

        // 转出分红
        pool.token.transfer(msg.sender, claimable);

        emit DividendReleased(poolId, msg.sender, claimable);
    }

    /**
     * @dev 计算可领取分红
     */
    function getClaimableDividend(uint256 poolId, address user) public view returns (uint256) {
        Pool storage pool = pools[poolId];
        ShareInfo storage info = shareInfo[poolId][user];
        
        if (info.shares == 0) return 0;

        uint256 totalDividend = 0;
        DividendRecord[] storage records = dividendRecords[poolId];

        for (uint256 i = 0; i < records.length; i++) {
            DividendRecord storage record = records[i];
            if (record.timestamp <= info.lastClaimTime) continue;

            uint256 share = info.shares.mul(record.amount).div(record.totalShares);
            totalDividend = totalDividend.add(share);
        }

        return totalDividend;
    }

    /**
     * @dev 设置分红池状态
     */
    function setPoolStatus(uint256 poolId, bool isActive) external onlyOwner {
        require(poolId < poolCount, "Invalid pool ID");
        pools[poolId].isActive = isActive;
        emit PoolStatusChanged(poolId, isActive);
    }

    /**
     * @dev 设置最小领取间隔
     */
    function setMinClaimInterval(uint256 interval) external onlyOwner {
        minClaimInterval = interval;
    }

    /**
     * @dev 暂停/恢复系统
     */
    function setPaused(bool _paused) external onlyOwner {
        paused = _paused;
    }

    /**
     * @dev 获取分红池信息
     */
    function getPoolInfo(uint256 poolId) external view returns (
        address token,
        uint256 totalShares,
        uint256 totalReleased,
        uint256 lastUpdateTime,
        bool isActive
    ) {
        require(poolId < poolCount, "Invalid pool ID");
        Pool storage pool = pools[poolId];
        return (
            address(pool.token),
            pool.totalShares,
            pool.totalReleased,
            pool.lastUpdateTime,
            pool.isActive
        );
    }

    /**
     * @dev 获取用户份额信息
     */
    function getUserInfo(uint256 poolId, address user) external view returns (
        uint256 shares,
        uint256 released,
        uint256 lastClaimTime,
        uint256 claimable
    ) {
        ShareInfo storage info = shareInfo[poolId][user];
        return (
            info.shares,
            info.released,
            info.lastClaimTime,
            getClaimableDividend(poolId, user)
        );
    }

    /**
     * @dev 获取分红记录数量
     */
    function getDividendRecordCount(uint256 poolId) external view returns (uint256) {
        return dividendRecords[poolId].length;
    }

    /**
     * @dev 获取分红记录
     */
    function getDividendRecord(uint256 poolId, uint256 index) external view returns (
        uint256 amount,
        uint256 timestamp,
        uint256 totalShares
    ) {
        require(poolId < poolCount, "Invalid pool ID");
        require(index < dividendRecords[poolId].length, "Invalid index");

        DividendRecord storage record = dividendRecords[poolId][index];
        return (
            record.amount,
            record.timestamp,
            record.totalShares
        );
    }

    /**
     * @dev 批量获取分红记录
     */
    function getDividendRecords(
        uint256 poolId,
        uint256 offset,
        uint256 limit
    ) external view returns (
        uint256[] memory amounts,
        uint256[] memory timestamps,
        uint256[] memory totalShares
    ) {
        require(poolId < poolCount, "Invalid pool ID");
        require(offset < dividendRecords[poolId].length, "Invalid offset");

        uint256 end = offset.add(limit);
        if (end > dividendRecords[poolId].length) {
            end = dividendRecords[poolId].length;
        }
        uint256 size = end.sub(offset);

        amounts = new uint256[](size);
        timestamps = new uint256[](size);
        totalShares = new uint256[](size);

        for (uint256 i = 0; i < size; i++) {
            DividendRecord storage record = dividendRecords[poolId][offset.add(i)];
            amounts[i] = record.amount;
            timestamps[i] = record.timestamp;
            totalShares[i] = record.totalShares;
        }

        return (amounts, timestamps, totalShares);
    }
}

3. 功能说明

3.1 分红池管理

  • 创建分红池
  • 更新份额
  • 添加分红

3.2 分红发放

  • 分红计算
  • 分红领取
  • 记录管理

3.3 状态查询

  • 池信息查询
  • 用户信息查询
  • 分红记录查询

4. 安全机制

4.1 分红控制

  • 最小份额限制
  • 领取间隔控制
  • 暂停机制

4.2 访问控制

  • 权限管理
  • 重入保护
  • 参数验证

4.3 状态管理

  • 池状态管理
  • 份额更新
  • 记录维护

5. 使用示例

5.1 创建分红池

javascript
await dividendPool.createPool(token.address);

5.2 更新份额

javascript
const shares = ethers.utils.parseEther("100");
await dividendPool.updateShares(0, userAddress, shares);

5.3 领取分红

javascript
await dividendPool.claimDividend(0);

6. 总结

该代币分红池系统实现了完整的分红管理功能,包括:

  • 多币种分红支持
  • 灵活的份额管理
  • 自动化分红发放
  • 完整的记录系统
  • 完善的安全机制

系统通过精心设计的分红计算模型和安全机制,确保了分红过程的公平性和可靠性。

常见问题解答(FAQ)

基础概念

Q: 什么是代币分红池?

A: 代币分红池是一种收益分配机制,主要特点包括:

  • 自动分配项目收益
  • 按持币比例分红
  • 支持多币种分红
  • 定期结算收益
  • 透明公平分配

Q: 分红机制有哪些类型?

A: 主要类型包括:

  • 定期分红型
  • 实时分红型
  • 阈值触发型
  • 混合分红型
  • 动态调节型

操作相关

Q: 如何参与代币分红?

A: 参与步骤包括:

  • 持有平台代币
  • 质押到分红池
  • 等待分红周期
  • 领取分红收益
  • 复投或提现

Q: 如何优化分红效果?

A: 优化方法包括:

  • 调整分红周期
  • 优化分配算法
  • 设置最低门槛
  • 实施复投激励
  • 保持收益稳定

安全相关

Q: 分红机制有哪些风险?

A: 主要风险包括:

  • 合约漏洞
  • 分配不公平
  • 收益波动
  • 质押风险
  • 市场操纵

Q: 如何确保分红安全?

A: 安全措施包括:

  • 多重签名控制
  • 分红池隔离
  • 收益来源验证
  • 分配算法审计
  • 应急暂停机制

Released under the MIT License by Vogeb.