Token Distribution System
The token distribution system is a mechanism for managing token allocation and distribution. This tutorial will explain how to implement a secure and reliable token distribution system.
Features
- Distribution Management
- Batch Distribution
- Locking Mechanism
- Access Control
- Emergency Handling
Contract Implementation
// 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";
import "@openzeppelin/contracts/security/Pausable.sol";
/**
* @title TokenDistribution
* @dev Token distribution contract implementation
*/
contract TokenDistribution is Ownable, ReentrancyGuard, Pausable {
using SafeMath for uint256;
// Distribution plan
struct Distribution {
uint256 amount; // Distribution amount
uint256 startTime; // Start time
uint256 duration; // Duration
uint256 interval; // Release interval
uint256 released; // Released amount
bool isActive; // Whether active
}
// Recipient information
struct Recipient {
uint256 totalAmount; // Total allocated amount
uint256 releasedAmount; // Released amount
uint256 lastRelease; // Last release time
bool isActive; // Whether active
}
// Configuration information
struct DistributionConfig {
uint256 minAmount; // Minimum allocation
uint256 maxAmount; // Maximum allocation
uint256 minDuration; // Minimum period
uint256 maxDuration; // Maximum period
bool requiresApproval; // Whether approval required
bool isActive; // Whether active
}
// State variables
IERC20 public token; // Token contract
mapping(bytes32 => Distribution) public distributions; // Distribution plans
mapping(bytes32 => mapping(address => Recipient)) public recipients; // Recipient information
mapping(address => bool) public operators; // Operators
DistributionConfig public config; // Configuration information
// Events
event DistributionCreated(bytes32 indexed id, uint256 amount, uint256 startTime, uint256 duration);
event DistributionUpdated(bytes32 indexed id, bool isActive);
event TokensDistributed(bytes32 indexed id, address indexed recipient, uint256 amount);
event RecipientUpdated(bytes32 indexed id, address indexed recipient, uint256 amount, bool isActive);
event OperatorUpdated(address indexed operator, bool status);
event ConfigUpdated(uint256 minAmount, uint256 maxAmount, uint256 minDuration, uint256 maxDuration);
/**
* @dev Constructor
*/
constructor(
address _token,
uint256 _minAmount,
uint256 _maxAmount,
uint256 _minDuration,
uint256 _maxDuration
) {
require(_token != address(0), "Invalid token");
token = IERC20(_token);
config = DistributionConfig({
minAmount: _minAmount,
maxAmount: _maxAmount,
minDuration: _minDuration,
maxDuration: _maxDuration,
requiresApproval: true,
isActive: true
});
}
/**
* @dev Create distribution plan
*/
function createDistribution(
uint256 _amount,
uint256 _startTime,
uint256 _duration,
uint256 _interval
) external onlyOperator whenNotPaused returns (bytes32) {
require(config.isActive, "Distribution not active");
require(_amount >= config.minAmount && _amount <= config.maxAmount, "Invalid amount");
require(_duration >= config.minDuration && _duration <= config.maxDuration, "Invalid duration");
require(_interval > 0 && _interval <= _duration, "Invalid interval");
require(_startTime >= block.timestamp, "Invalid start time");
bytes32 id = keccak256(abi.encodePacked(
block.timestamp,
_amount,
_startTime,
_duration,
_interval
));
distributions[id] = Distribution({
amount: _amount,
startTime: _startTime,
duration: _duration,
interval: _interval,
released: 0,
isActive: true
});
emit DistributionCreated(id, _amount, _startTime, _duration);
return id;
}
/**
* @dev Add recipient
*/
function addRecipient(
bytes32 _id,
address _recipient,
uint256 _amount
) external onlyOperator {
require(_recipient != address(0), "Invalid recipient");
Distribution storage dist = distributions[_id];
require(dist.isActive, "Distribution not active");
require(dist.released.add(_amount) <= dist.amount, "Exceeds distribution amount");
recipients[_id][_recipient] = Recipient({
totalAmount: _amount,
releasedAmount: 0,
lastRelease: 0,
isActive: true
});
emit RecipientUpdated(_id, _recipient, _amount, true);
}
/**
* @dev Batch add recipients
*/
function addRecipients(
bytes32 _id,
address[] calldata _recipients,
uint256[] calldata _amounts
) external onlyOperator {
require(_recipients.length == _amounts.length, "Length mismatch");
Distribution storage dist = distributions[_id];
require(dist.isActive, "Distribution not active");
uint256 totalAmount = 0;
for (uint256 i = 0; i < _amounts.length; i++) {
totalAmount = totalAmount.add(_amounts[i]);
}
require(dist.released.add(totalAmount) <= dist.amount, "Exceeds distribution amount");
for (uint256 i = 0; i < _recipients.length; i++) {
address recipient = _recipients[i];
uint256 amount = _amounts[i];
require(recipient != address(0), "Invalid recipient");
recipients[_id][recipient] = Recipient({
totalAmount: amount,
releasedAmount: 0,
lastRelease: 0,
isActive: true
});
emit RecipientUpdated(_id, recipient, amount, true);
}
}
/**
* @dev Release tokens
*/
function release(
bytes32 _id,
address _recipient
) external nonReentrant whenNotPaused returns (uint256) {
Distribution storage dist = distributions[_id];
require(dist.isActive, "Distribution not active");
require(block.timestamp >= dist.startTime, "Not started");
Recipient storage recipient = recipients[_id][_recipient];
require(recipient.isActive, "Recipient not active");
uint256 releasable = getReleasableAmount(_id, _recipient);
require(releasable > 0, "No tokens to release");
recipient.releasedAmount = recipient.releasedAmount.add(releasable);
recipient.lastRelease = block.timestamp;
dist.released = dist.released.add(releasable);
require(
token.transfer(_recipient, releasable),
"Transfer failed"
);
emit TokensDistributed(_id, _recipient, releasable);
return releasable;
}
/**
* @dev Batch release tokens
*/
function batchRelease(
bytes32 _id,
address[] calldata _recipients
) external nonReentrant whenNotPaused returns (uint256) {
uint256 totalReleased = 0;
for (uint256 i = 0; i < _recipients.length; i++) {
uint256 released = release(_id, _recipients[i]);
totalReleased = totalReleased.add(released);
}
return totalReleased;
}
/**
* @dev Calculate releasable amount
*/
function getReleasableAmount(
bytes32 _id,
address _recipient
) public view returns (uint256) {
Distribution storage dist = distributions[_id];
Recipient storage recipient = recipients[_id][_recipient];
if (!dist.isActive || !recipient.isActive || block.timestamp < dist.startTime) {
return 0;
}
uint256 elapsedTime = block.timestamp.sub(dist.startTime);
if (elapsedTime > dist.duration) {
return recipient.totalAmount.sub(recipient.releasedAmount);
}
uint256 intervals = elapsedTime.div(dist.interval);
uint256 releasable = recipient.totalAmount.mul(intervals).div(dist.duration.div(dist.interval));
return releasable.sub(recipient.releasedAmount);
}
}
System Architecture
1. Core Components
- Distribution Contract: Manages token distribution
- Plan Management: Controls distribution plans
- Recipient System: Manages recipients
- Release Module: Handles token releases
2. Process Flow
- Create distribution plan
- Add recipients
- Calculate releases
- Execute distributions
- Track progress
Security Measures
1. Access Control
- Operator permissions
- Plan management
- Release controls
- Emergency pause
2. Distribution Security
- Amount validation
- Timing controls
- Release tracking
- Balance checks
Best Practices
1. Implementation Guidelines
- Validate all inputs
- Implement proper access control
- Handle edge cases
- Maintain comprehensive logs
2. Operation Guidelines
- Regular security audits
- Plan management
- Emergency response plan
- Regular status reviews
FAQ
1. Basic Concepts
Q: What is token distribution? A: Token distribution is a mechanism for allocating and releasing tokens to multiple recipients according to predefined schedules and rules.
Q: How does distribution scheduling work? A: Distribution scheduling involves:
- Plan creation
- Timing control
- Release calculation
- Progress tracking
2. Security
Q: How to ensure distribution security? A: Security measures include:
- Access control
- Amount validation
- Release verification
- Emergency mechanisms
- Regular audits
Q: How to handle distribution attacks? A: Protection measures include:
- Input validation
- Rate limiting
- Balance checks
- Status monitoring
- Quick response plan
3. Operations
Q: How to manage distributions effectively? A: Management strategies include:
- Plan organization
- Recipient management
- Release scheduling
- Progress monitoring
- Documentation
Q: How to handle distribution issues? A: Issue resolution includes:
- Error checking
- Status verification
- Balance reconciliation
- Support system
- Clear communication
4. Maintenance
Q: How to maintain the distribution system? A: Maintenance includes:
- Regular updates
- Performance monitoring
- Security checks
- Plan reviews
- Documentation updates
Q: How to monitor distribution progress? A: Monitoring includes:
- Release tracking
- Balance checking
- Status updates
- Error logging
- Success metrics