Skip to content

Token Blacklist System

The token blacklist is a system for managing address transaction restrictions. This tutorial will explain how to implement a secure and reliable blacklist system.

Features

  • Blacklist Management
  • Transaction Restrictions
  • Access Control
  • Security Protection
  • Emergency Handling

Contract Implementation

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/security/Pausable.sol";

/**
 * @title TokenBlacklist
 * @dev Token blacklist contract implementation
 */
contract TokenBlacklist is Ownable, ReentrancyGuard, Pausable {
    // Blacklist information
    struct BlacklistInfo {
        bool isBlacklisted;      // Whether blacklisted
        uint256 startTime;       // Start time
        uint256 endTime;         // End time
        string reason;           // Reason
        address operator;        // Operator
    }

    // Configuration information
    struct BlacklistConfig {
        bool requiresReason;     // Whether reason is required
        bool requiresEndTime;    // Whether end time is required
        bool requiresOperator;   // Whether operator is required
        bool isActive;           // Whether active
    }

    // State variables
    mapping(address => BlacklistInfo) public blacklist;           // Blacklist
    mapping(address => bool) public operators;                    // Operators
    BlacklistConfig public config;                               // Configuration information
    uint256 public blacklistCount;                              // Blacklist count

    // Events
    event AddedToBlacklist(address indexed account, uint256 startTime, uint256 endTime, string reason);
    event RemovedFromBlacklist(address indexed account);
    event OperatorUpdated(address indexed operator, bool status);
    event ConfigUpdated(bool requiresReason, bool requiresEndTime, bool requiresOperator);

    /**
     * @dev Constructor
     */
    constructor(
        bool _requiresReason,
        bool _requiresEndTime,
        bool _requiresOperator
    ) {
        config = BlacklistConfig({
            requiresReason: _requiresReason,
            requiresEndTime: _requiresEndTime,
            requiresOperator: _requiresOperator,
            isActive: true
        });
    }

    /**
     * @dev Add to blacklist
     */
    function addToBlacklist(
        address _account,
        uint256 _endTime,
        string calldata _reason
    ) external onlyOperator whenNotPaused {
        require(_account != address(0), "Invalid address");
        require(!blacklist[_account].isBlacklisted, "Already blacklisted");
        
        if (config.requiresEndTime) {
            require(_endTime > block.timestamp, "Invalid end time");
        }
        
        if (config.requiresReason) {
            require(bytes(_reason).length > 0, "Reason required");
        }

        blacklist[_account] = BlacklistInfo({
            isBlacklisted: true,
            startTime: block.timestamp,
            endTime: _endTime,
            reason: _reason,
            operator: msg.sender
        });

        blacklistCount++;
        emit AddedToBlacklist(_account, block.timestamp, _endTime, _reason);
    }

    /**
     * @dev Batch add to blacklist
     */
    function batchAddToBlacklist(
        address[] calldata _accounts,
        uint256[] calldata _endTimes,
        string[] calldata _reasons
    ) external onlyOperator whenNotPaused {
        require(
            _accounts.length == _endTimes.length && 
            _accounts.length == _reasons.length,
            "Length mismatch"
        );

        for (uint256 i = 0; i < _accounts.length; i++) {
            require(_accounts[i] != address(0), "Invalid address");
            require(!blacklist[_accounts[i]].isBlacklisted, "Already blacklisted");
            
            if (config.requiresEndTime) {
                require(_endTimes[i] > block.timestamp, "Invalid end time");
            }
            
            if (config.requiresReason) {
                require(bytes(_reasons[i]).length > 0, "Reason required");
            }

            blacklist[_accounts[i]] = BlacklistInfo({
                isBlacklisted: true,
                startTime: block.timestamp,
                endTime: _endTimes[i],
                reason: _reasons[i],
                operator: msg.sender
            });

            blacklistCount++;
            emit AddedToBlacklist(_accounts[i], block.timestamp, _endTimes[i], _reasons[i]);
        }
    }

    /**
     * @dev Remove from blacklist
     */
    function removeFromBlacklist(
        address _account
    ) external onlyOperator whenNotPaused {
        require(blacklist[_account].isBlacklisted, "Not blacklisted");

        delete blacklist[_account];
        blacklistCount--;
        emit RemovedFromBlacklist(_account);
    }

    /**
     * @dev Batch remove from blacklist
     */
    function batchRemoveFromBlacklist(
        address[] calldata _accounts
    ) external onlyOperator whenNotPaused {
        for (uint256 i = 0; i < _accounts.length; i++) {
            require(blacklist[_accounts[i]].isBlacklisted, "Not blacklisted");

            delete blacklist[_accounts[i]];
            blacklistCount--;
            emit RemovedFromBlacklist(_accounts[i]);
        }
    }

    /**
     * @dev Check if address is blacklisted
     */
    function isBlacklisted(
        address _account
    ) public view returns (bool) {
        if (!blacklist[_account].isBlacklisted) {
            return false;
        }

        if (blacklist[_account].endTime > 0 && 
            block.timestamp > blacklist[_account].endTime) {
            return false;
        }

        return true;
    }

    /**
     * @dev Get blacklist information
     */
    function getBlacklistInfo(
        address _account
    ) external view returns (
        bool isBlacklisted,
        uint256 startTime,
        uint256 endTime,
        string memory reason,
        address operator
    ) {
        BlacklistInfo storage info = blacklist[_account];
        return (
            info.isBlacklisted,
            info.startTime,
            info.endTime,
            info.reason,
            info.operator
        );
    }

    /**
     * @dev Update operator
     */
    function updateOperator(
        address _operator,
        bool _status
    ) external onlyOwner {
        operators[_operator] = _status;
        emit OperatorUpdated(_operator, _status);
    }

    /**
     * @dev Update configuration
     */
    function updateConfig(
        bool _requiresReason,
        bool _requiresEndTime,
        bool _requiresOperator
    ) external onlyOwner {
        config.requiresReason = _requiresReason;
        config.requiresEndTime = _requiresEndTime;
        config.requiresOperator = _requiresOperator;
        emit ConfigUpdated(_requiresReason, _requiresEndTime, _requiresOperator);
    }

    /**
     * @dev Pause blacklist
     */
    function pause() external onlyOwner {
        _pause();
    }

    /**
     * @dev Unpause blacklist
     */
    function unpause() external onlyOwner {
        _unpause();
    }
}

System Architecture

1. Core Components

  • Blacklist Contract: Manages address restrictions
  • Operator System: Controls blacklist operations
  • Configuration Module: Manages system settings
  • Security Module: Handles emergency situations

2. Process Flow

  1. Operator adds address to blacklist
  2. System validates requirements
  3. Blacklist status is updated
  4. Events are emitted
  5. Restrictions are enforced

Security Measures

1. Access Control

  • Operator permissions
  • Owner privileges
  • Pause mechanism
  • Requirement validation

2. Data Security

  • Input validation
  • State management
  • Event logging
  • Emergency handling

Best Practices

1. Implementation Guidelines

  • Validate all inputs
  • Implement proper access control
  • Handle edge cases
  • Maintain comprehensive logs

2. Operation Guidelines

  • Regular security audits
  • Operator management
  • Emergency response plan
  • Regular configuration reviews

FAQ

1. Basic Concepts

Q: What is a token blacklist? A: A token blacklist is a system that restricts specific addresses from participating in token transactions, used for security and compliance purposes.

Q: How does blacklisting work? A: Blacklisting involves:

  • Address validation
  • Restriction period setting
  • Reason documentation
  • Status monitoring

2. Security

Q: How to ensure blacklist security? A: Security measures include:

  • Access control
  • Input validation
  • Event logging
  • Emergency mechanisms
  • Regular audits

Q: How to handle blacklist attacks? A: Protection measures include:

  • Operator verification
  • Input validation
  • Status monitoring
  • Emergency pause
  • Quick response plan

3. Operations

Q: How to manage blacklist effectively? A: Management strategies include:

  • Regular reviews
  • Clear documentation
  • Operator training
  • Status monitoring
  • Process automation

Q: How to handle disputes? A: Dispute resolution includes:

  • Clear documentation
  • Appeal process
  • Review mechanism
  • Transparent communication
  • Fair resolution

4. Maintenance

Q: How to maintain the blacklist system? A: Maintenance includes:

  • Regular updates
  • Performance monitoring
  • Security checks
  • Configuration reviews
  • Operator training

Q: How to monitor system status? A: Monitoring includes:

  • Event tracking
  • Status checks
  • Performance metrics
  • Error logging
  • Usage analytics

Released under the MIT License by Vogeb.