代币投票权重系统
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 TokenVoteWeight
* @dev 代币投票权重合约
*/
contract TokenVoteWeight is Ownable, ReentrancyGuard {
using SafeMath for uint256;
// 权重信息
struct WeightInfo {
uint256 baseWeight; // 基础权重
uint256 timeWeight; // 时间权重
uint256 activityWeight; // 活动权重
uint256 lockWeight; // 锁定权重
uint256 lastUpdateTime; // 最后更新时间
address delegateTo; // 委托地址
}
// 锁定信息
struct LockInfo {
uint256 amount; // 锁定数量
uint256 startTime; // 开始时间
uint256 endTime; // 结束时间
uint256 multiplier; // 权重倍数
}
// 状态变量
IERC20 public token; // 投票代币
mapping(address => WeightInfo) public weightInfo; // 权重信息
mapping(address => LockInfo[]) public lockInfo; // 锁定信息
mapping(address => uint256) public totalLocked; // 总锁定量
mapping(address => uint256) public activityPoints; // 活动积分
mapping(address => mapping(address => uint256)) public delegatedPower; // 委托权重
// 常量
uint256 public constant PRECISION = 1e18; // 精度
uint256 public constant MAX_LOCK_TIME = 4 * 365 days; // 最大锁定时间(4年)
uint256 public constant MAX_MULTIPLIER = 4e18; // 最大倍数(4倍)
uint256 public constant MIN_LOCK_TIME = 7 days; // 最小锁定时间
// 事件
event WeightUpdated(address indexed user, uint256 newWeight);
event TokensLocked(address indexed user, uint256 amount, uint256 duration);
event TokensUnlocked(address indexed user, uint256 amount);
event DelegationChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event ActivityPointsAdded(address indexed user, uint256 points);
/**
* @dev 构造函数
*/
constructor(IERC20 _token) {
token = _token;
}
/**
* @dev 锁定代币
*/
function lock(uint256 amount, uint256 duration) external nonReentrant {
require(amount > 0, "Amount must be greater than 0");
require(duration >= MIN_LOCK_TIME, "Duration too short");
require(duration <= MAX_LOCK_TIME, "Duration too long");
// 转入代币
token.transferFrom(msg.sender, address(this), amount);
// 计算权重倍数
uint256 multiplier = calculateMultiplier(duration);
// 创建锁定记录
lockInfo[msg.sender].push(LockInfo({
amount: amount,
startTime: block.timestamp,
endTime: block.timestamp + duration,
multiplier: multiplier
}));
// 更新总锁定量
totalLocked[msg.sender] = totalLocked[msg.sender].add(amount);
// 更新权重
updateWeight(msg.sender);
emit TokensLocked(msg.sender, amount, duration);
}
/**
* @dev 解锁代币
*/
function unlock(uint256 lockId) external nonReentrant {
require(lockId < lockInfo[msg.sender].length, "Invalid lock ID");
LockInfo storage info = lockInfo[msg.sender][lockId];
require(block.timestamp >= info.endTime, "Lock not expired");
require(info.amount > 0, "Already unlocked");
uint256 amount = info.amount;
info.amount = 0;
// 更新总锁定量
totalLocked[msg.sender] = totalLocked[msg.sender].sub(amount);
// 更新权重
updateWeight(msg.sender);
// 转出代币
token.transfer(msg.sender, amount);
emit TokensUnlocked(msg.sender, amount);
}
/**
* @dev 委托投票权
*/
function delegate(address delegatee) external {
address currentDelegate = weightInfo[msg.sender].delegateTo;
WeightInfo storage delegatorWeight = weightInfo[msg.sender];
if (currentDelegate != address(0)) {
delegatedPower[currentDelegate][msg.sender] = 0;
}
if (delegatee != address(0)) {
delegatedPower[delegatee][msg.sender] = getTotalWeight(msg.sender);
}
delegatorWeight.delegateTo = delegatee;
emit DelegationChanged(msg.sender, currentDelegate, delegatee);
}
/**
* @dev 添加活动积分
*/
function addActivityPoints(address user, uint256 points) external onlyOwner {
activityPoints[user] = activityPoints[user].add(points);
updateWeight(user);
emit ActivityPointsAdded(user, points);
}
/**
* @dev 更新权重
*/
function updateWeight(address user) public {
WeightInfo storage info = weightInfo[user];
// 更新基础权重
info.baseWeight = totalLocked[user];
// 更新时间权重
info.timeWeight = calculateTimeWeight(user);
// 更新活动权重
info.activityWeight = calculateActivityWeight(user);
// 更新锁定权重
info.lockWeight = calculateLockWeight(user);
info.lastUpdateTime = block.timestamp;
emit WeightUpdated(user, getTotalWeight(user));
}
/**
* @dev 计算总权重
*/
function getTotalWeight(address user) public view returns (uint256) {
WeightInfo storage info = weightInfo[user];
return info.baseWeight
.add(info.timeWeight)
.add(info.activityWeight)
.add(info.lockWeight);
}
/**
* @dev 计算时间权重
*/
function calculateTimeWeight(address user) public view returns (uint256) {
uint256 totalWeight = 0;
LockInfo[] storage locks = lockInfo[user];
for (uint256 i = 0; i < locks.length; i++) {
if (locks[i].amount == 0) continue;
uint256 timeElapsed = block.timestamp.sub(locks[i].startTime);
uint256 weight = locks[i].amount.mul(timeElapsed).div(MAX_LOCK_TIME);
totalWeight = totalWeight.add(weight);
}
return totalWeight;
}
/**
* @dev 计算活动权重
*/
function calculateActivityWeight(address user) public view returns (uint256) {
return activityPoints[user].mul(PRECISION).div(1000); // 0.1% per point
}
/**
* @dev 计算锁定权重
*/
function calculateLockWeight(address user) public view returns (uint256) {
uint256 totalWeight = 0;
LockInfo[] storage locks = lockInfo[user];
for (uint256 i = 0; i < locks.length; i++) {
if (locks[i].amount == 0) continue;
uint256 weight = locks[i].amount.mul(locks[i].multiplier).div(PRECISION);
totalWeight = totalWeight.add(weight);
}
return totalWeight;
}
/**
* @dev 计算权重倍数
*/
function calculateMultiplier(uint256 duration) public pure returns (uint256) {
uint256 multiplier = PRECISION.add(
duration.mul(MAX_MULTIPLIER.sub(PRECISION)).div(MAX_LOCK_TIME)
);
return multiplier;
}
/**
* @dev 获取委托权重
*/
function getDelegatedPower(address delegatee) external view returns (uint256) {
uint256 totalPower = 0;
uint256 length = getAccountsLength();
for (uint256 i = 0; i < length; i++) {
address delegator = getAccount(i);
if (weightInfo[delegator].delegateTo == delegatee) {
totalPower = totalPower.add(getTotalWeight(delegator));
}
}
return totalPower;
}
/**
* @dev 获取账户列表长度
*/
function getAccountsLength() public view returns (uint256) {
// 实现账户列表存储和查询
return 0;
}
/**
* @dev 获取账户地址
*/
function getAccount(uint256 index) public view returns (address) {
// 实现账户地址查询
return address(0);
}
/**
* @dev 获取锁定记录数量
*/
function getLockCount(address user) external view returns (uint256) {
return lockInfo[user].length;
}
/**
* @dev 获取用户权重信息
*/
function getWeightInfo(address user) external view returns (
uint256 baseWeight,
uint256 timeWeight,
uint256 activityWeight,
uint256 lockWeight,
uint256 lastUpdateTime,
address delegateTo
) {
WeightInfo storage info = weightInfo[user];
return (
info.baseWeight,
info.timeWeight,
info.activityWeight,
info.lockWeight,
info.lastUpdateTime,
info.delegateTo
);
}
/**
* @dev 获取锁定信息
*/
function getLockInfo(address user, uint256 lockId) external view returns (
uint256 amount,
uint256 startTime,
uint256 endTime,
uint256 multiplier
) {
require(lockId < lockInfo[user].length, "Invalid lock ID");
LockInfo storage info = lockInfo[user][lockId];
return (
info.amount,
info.startTime,
info.endTime,
info.multiplier
);
}
}
3. 功能说明
3.1 权重管理
- 基础权重计算
- 时间权重计算
- 活动权重计算
- 锁定权重计算
3.2 锁定机制
- 代币锁定
- 解锁操作
- 权重倍数计算
3.3 委托机制
- 权重委托
- 委托权重计算
- 委托关系管理
4. 安全机制
4.1 权重控制
- 最大锁定时间
- 最大权重倍数
- 最小锁定时间
4.2 访问控制
- 权限管理
- 重入保护
- 参数验证
4.3 状态管理
- 权重更新
- 锁定状态
- 委托关系
5. 使用示例
5.1 锁定代币
javascript
const amount = ethers.utils.parseEther("100");
const duration = 365 * 24 * 60 * 60; // 1年
await token.approve(voteWeight.address, amount);
await voteWeight.lock(amount, duration);
5.2 委托权重
javascript
await voteWeight.delegate(delegatee);
5.3 查询权重
javascript
const weight = await voteWeight.getTotalWeight(userAddress);
console.log("总权重:", ethers.utils.formatEther(weight));
6. 总结
该代币投票权重系统实现了完整的权重管理功能,包括:
- 多维度权重计算
- 灵活的锁定机制
- 权重委托功能
- 活动积分系统
- 完善的安全机制
系统通过精心设计的权重计算模型和安全机制,确保了投票权重的公平性和可靠性。
常见问题解答(FAQ)
1. 基本概念
Q: 什么是代币投票权重? A: 代币投票权重是一种治理机制,主要特点包括:
- 基于代币量的权重
- 时间锁定加成
- 活动权重奖励
- 委托投票机制
- 动态权重调整
Q: 投票权重有哪些类型? A: 主要类型包括:
- 基础权重
- 时间权重
- 活动权重
- 锁定权重
- 委托权重
2. 功能相关
Q: 如何计算投票权重? A: 计算方法:
solidity
function calculateVoteWeight(
uint256 amount,
uint256 lockTime,
uint256 activityPoints
) public pure returns (uint256) {
// 1. 基础权重
uint256 baseWeight = amount;
// 2. 时间权重
uint256 timeWeight = amount * lockTime / MAX_LOCK_TIME;
// 3. 活动权重
uint256 activityWeight = activityPoints * POINT_MULTIPLIER;
// 4. 总权重
return baseWeight + timeWeight + activityWeight;
}
Q: 如何管理委托权重? A: 管理策略:
- 委托记录
- 权重转移
- 撤销机制
- 收益分配
- 状态更新
3. 安全相关
Q: 权重系统有什么风险? A: 主要风险包括:
- 权重操纵
- 委托攻击
- 时间攻击
- 计算溢出
- 权限滥用
Q: 如何保护投票权重? A: 安全措施包括:
- 权重上限
- 锁定期限
- 委托限制
- 活动验证
- 权限控制
4. 优化相关
Q: 如何优化权重计算? A: 优化策略:
- 缓存计算
- 批量更新
- 存储优化
- 逻辑简化
- Gas优化
Q: 如何提高系统效率? A: 改进方案:
- 异步更新
- 状态压缩
- 批量处理
- 事件优化
- 存储优化
5. 实现细节
Q: 如何实现权重更新? A: 实现机制:
solidity
function updateWeight(
address user,
uint256 newAmount,
uint256 lockTime
) internal {
// 1. 获取用户信息
WeightInfo storage info = weightInfo[user];
// 2. 更新基础权重
info.baseWeight = newAmount;
// 3. 更新时间权重
if (lockTime > 0) {
info.timeWeight = calculateTimeWeight(newAmount, lockTime);
}
// 4. 更新总权重
emit WeightUpdated(user, getTotalWeight(user));
}
Q: 如何处理委托变更? A: 处理机制:
- 权重转移
- 状态更新
- 收益调整
- 记录变更
- 事件通知
6. 最佳实践
Q: 权重系统开发建议? A: 开发建议:
- 模块化设计
- 完整测试
- 安全审计
- 文档完善
- 监控预警
Q: 如何提高系统可靠性? A: 改进方案:
- 故障检测
- 自动恢复
- 状态验证
- 日志记录
- 备份机制
7. 错误处理
Q: 常见错误及解决方案? A: 错误类型:
"Invalid amount"
: 检查数量"Lock time expired"
: 验证时间"Not delegated"
: 检查委托"Weight overflow"
: 验证计算"Not authorized"
: 确认权限
Q: 如何处理异常情况? A: 处理机制:
- 状态回滚
- 错误记录
- 通知机制
- 手动修正
- 补偿机制
8. 升级维护
Q: 如何升级权重系统? A: 升级策略:
- 代理合约
- 数据迁移
- 兼容处理
- 测试验证
- 平滑过渡
Q: 如何监控系统状态? A: 监控方案:
- 权重变化
- 委托状态
- 活动记录
- 异常检测
- 性能指标
9. 与其他系统集成
Q: 如何与治理系统集成? A: 集成方案:
- 提案权重
- 投票计算
- 状态同步
- 权限管理
- 结果验证
Q: 如何实现跨链权重? A: 实现策略:
- 跨链消息
- 权重映射
- 状态同步
- 安全验证
- 一致性保证