Skip to content

Token Upgrade System

The token upgrade system is used to implement secure smart contract upgrades, allowing contract logic to be updated while maintaining state and balances. This tutorial will explain how to implement an upgradeable token system.

Features

  • Transparent proxy pattern
  • UUPS proxy pattern
  • State-preserving upgrades
  • Permission control mechanism
  • Security check mechanism

Contract Implementation

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

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

/**
 * @title UpgradeableToken
 * @dev Upgradeable token contract implementation (UUPS pattern)
 */
contract UpgradeableToken is 
    Initializable,
    ERC20Upgradeable,
    OwnableUpgradeable,
    UUPSUpgradeable
{
    // Version number
    uint256 public version;
    
    // Minter permission mapping
    mapping(address => bool) public minters;
    
    // Blacklist mapping
    mapping(address => bool) public blacklist;
    
    // Events
    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);
    event Blacklisted(address indexed account);
    event UnBlacklisted(address indexed account);
    event TokensRecovered(address indexed token, uint256 amount);

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    /**
     * @dev Initialization function (replaces constructor)
     */
    function initialize(
        string memory name,
        string memory symbol,
        uint256 initialSupply
    ) public initializer {
        __ERC20_init(name, symbol);
        __Ownable_init();
        __UUPSUpgradeable_init();
        
        version = 1;
        _mint(msg.sender, initialSupply);
    }

    /**
     * @dev Mint tokens (minters only)
     */
    function mint(address to, uint256 amount) external {
        require(minters[msg.sender], "Not a minter");
        _mint(to, amount);
    }

    /**
     * @dev Burn tokens
     */
    function burn(uint256 amount) external {
        _burn(msg.sender, amount);
    }

    /**
     * @dev Add minter (owner only)
     */
    function addMinter(address account) external onlyOwner {
        require(account != address(0), "Invalid address");
        require(!minters[account], "Already a minter");
        minters[account] = true;
        emit MinterAdded(account);
    }

    /**
     * @dev Remove minter (owner only)
     */
    function removeMinter(address account) external onlyOwner {
        require(minters[account], "Not a minter");
        minters[account] = false;
        emit MinterRemoved(account);
    }

    /**
     * @dev Add to blacklist (owner only)
     */
    function blacklistAddress(address account) external onlyOwner {
        require(account != address(0), "Invalid address");
        require(!blacklist[account], "Already blacklisted");
        blacklist[account] = true;
        emit Blacklisted(account);
    }

    /**
     * @dev Remove from blacklist (owner only)
     */
    function unBlacklistAddress(address account) external onlyOwner {
        require(blacklist[account], "Not blacklisted");
        blacklist[account] = false;
        emit UnBlacklisted(account);
    }

    /**
     * @dev Check blacklist before transfer
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);
        require(!blacklist[from] && !blacklist[to], "Address blacklisted");
    }

    /**
     * @dev Authorize upgrade (owner only)
     */
    function _authorizeUpgrade(address newImplementation) internal override onlyOwner {
        // Additional upgrade check logic can be added here
    }

    /**
     * @dev Get current version
     */
    function getVersion() external view returns (uint256) {
        return version;
    }

    /**
     * @dev Recover accidentally transferred tokens (owner only)
     */
    function recoverToken(
        address token,
        uint256 amount
    ) external onlyOwner {
        require(token != address(this), "Cannot recover native token");
        IERC20Upgradeable(token).transfer(owner(), amount);
        emit TokensRecovered(token, amount);
    }
}

/**
 * @title UpgradeableTokenV2
 * @dev Example of upgradeable token contract V2 version
 */
contract UpgradeableTokenV2 is UpgradeableToken {
    // New state variables
    uint256 public maxSupply;
    mapping(address => bool) public vips;
    
    // New events
    event VipAdded(address indexed account);
    event VipRemoved(address indexed account);
    
    /**
     * @dev Initialize V2 version
     */
    function initializeV2(uint256 _maxSupply) external reinitializer(2) {
        maxSupply = _maxSupply;
        version = 2;
    }
    
    /**
     * @dev Add VIP (owner only)
     */
    function addVip(address account) external onlyOwner {
        require(account != address(0), "Invalid address");
        require(!vips[account], "Already a VIP");
        vips[account] = true;
        emit VipAdded(account);
    }
    
    /**
     * @dev Remove VIP (owner only)
     */
    function removeVip(address account) external onlyOwner {
        require(vips[account], "Not a VIP");
        vips[account] = false;
        emit VipRemoved(account);
    }
    
    /**
     * @dev Override mint function, add max supply check
     */
    function mint(address to, uint256 amount) external override {
        require(minters[msg.sender], "Not a minter");
        require(totalSupply() + amount <= maxSupply, "Exceeds max supply");
        _mint(to, amount);
    }
    
    /**
     * @dev VIP users get fee-free transfers
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);
        // VIP users can bypass some restrictions
        if (vips[from] || vips[to]) {
            return;
        }
        // Restrictions for regular users can be added here
    }
}

Key Concepts

Proxy Pattern

The upgrade system supports:

  • UUPS proxy pattern
  • Transparent proxy pattern
  • State variable layout
  • Initialization mechanism

Version Management

Version control includes:

  • Version number tracking
  • Reinitialization
  • State migration
  • Compatibility check

Permission Control

Permission mechanism includes:

  • Owner permission
  • Mint permission
  • Upgrade authorization
  • Blacklist management

Security Considerations

  1. Upgrade Security

    • State layout check
    • Initialization protection
    • Permission verification
    • Logic verification
  2. Permission Management

    • Role separation
    • Permission check
    • Operation restriction
    • Event recording
  3. State Protection

    • Variable layout
    • Storage conflict
    • Data migration
    • Rollback mechanism
  4. Business Security

    • Blacklist mechanism
    • Transfer restriction
    • Mint control
    • Error handling

Best Practices

  1. Upgrade Process

    • Thorough testing
    • Gradual upgrade
    • State verification
    • Rollback预案
  2. Contract Design

    • Modular structure
    • Clear interface
    • Complete event
    • Detailed comments
  3. Test Verification

    • Unit test
    • Integration test
    • Upgrade test
    • Security audit
  4. Operation and Maintenance

    • Monitoring system
    • Log analysis
    • Emergency response
    • Regular inspection

Extended Features

  1. Multi-signature upgrade
  2. Time-lock upgrade
  3. Automated testing
  4. State migration tool
  5. Version rollback

Application Scenarios

  1. Function upgrade

    • Add new features
    • Fix vulnerabilities
    • Optimize performance
    • Update rules
  2. Governance upgrade

    • Parameter adjustment
    • Rule change
    • Permission update
    • Mechanism improvement
  3. Compatibility upgrade

    • Protocol adaptation
    • Standard update
    • Interface change
    • Ecological integration

Summary

The token upgrade system is an important tool for maintaining smart contracts. Through this tutorial, you can:

  • Implement secure contract upgrades
  • Manage versions and states
  • Control upgrade permissions
  • Ensure system stability

Frequently Asked Questions (FAQ)

1. Basic Concepts

Q: What is token upgrade? A: Token upgrade is a contract update mechanism, with the main features including:

  • Function update
  • Data migration
  • Version control
  • Compatibility handling
  • Smooth transition

Q: What types of upgrade systems are there? A: The main types include:

  • Proxy upgrade
  • Migration upgrade
  • Data upgrade
  • Function upgrade
  • Emergency upgrade

Q: How to design upgrade strategies? A: Design points:

solidity
function upgrade(
    address newImplementation
) public onlyAdmin {
    // 1. Verify new implementation
    require(newImplementation != address(0), "Invalid implementation");
    require(newImplementation != implementation(), "Same implementation");
    
    // 2. Check compatibility
    require(
        IUpgradeable(newImplementation).supportsInterface(type(IToken).interfaceId),
        "Incompatible interface"
    );
    
    // 3. Execute upgrade
    _upgradeTo(newImplementation);
    emit Upgraded(newImplementation);
}

Q: How to manage upgrade processes? A: Management strategies:

  • Version management
  • Test verification
  • Approval process
  • Backup recovery
  • Monitoring feedback

Q: What are the risks of upgrade systems? A: The main risks include:

  • Data loss
  • Function interruption
  • Compatibility issues
  • Permission abuse
  • Upgrade failure

Q: How to protect upgrade security? A: Security measures include:

  • Multi-signature
  • Time locking
  • Data verification
  • Rollback mechanism
  • Emergency预案

Q: How to optimize upgrade mechanisms? A: Optimization strategies:

  • Storage layout
  • Gas optimization
  • Data compression
  • Batch processing
  • Incremental update

Q: How to improve system efficiency? A: Improvement solutions:

  • Parallel processing
  • Cache optimization
  • Intelligent scheduling
  • Automated processing
  • Resource optimization

5. Implementation details

Q: How to implement data migration? A: Implementation mechanism:

solidity
function migrateData(
    address oldContract,
    address newContract
) internal {
    // 1. Read old data
    OldStorage storage oldStorage = OldStorage(oldContract);
    
    // 2. Convert format
    NewData memory newData = convertData(oldStorage);
    
    // 3. Write to new storage
    NewStorage storage newStorage = NewStorage(newContract);
    newStorage.store(newData);
}

Q: How to handle emergency rollbacks? A: Handling mechanism:

  • State saving
  • Quick rollback
  • Data recovery
  • Verification check
  • Log recording

6. Best practices

Q: Upgrade system development suggestions? A: Development suggestions:

  • Complete testing
  • Security audit
  • Documentation improvement
  • Version management
  • Monitoring and warning

Q: How to improve system reliability? A: Improvement solutions:

  • Fault detection
  • Automatic recovery
  • State verification
  • Log recording
  • Backup mechanism

7. Error handling

Q: Common errors and solutions? A: Error types:

  • "Invalid implementation": Check address
  • "Upgrade failed": Retry upgrade
  • "Data corrupted": Restore data
  • "Not authorized": Permission check
  • "System locked": Wait for unlock

Q: How to handle abnormal situations? A: Handling mechanism:

  • Automatic rollback
  • Manual recovery
  • Error reporting
  • Notification mechanism
  • Compensation processing

8. Upgrade maintenance

Q: How to manage upgrade versions? A: Upgrade strategies:

  • Version planning
  • Compatibility testing
  • Gray release
  • Monitoring feedback
  • Emergency handling

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

  • Version tracking
  • Performance monitoring
  • Error statistics
  • Usage analysis
  • Effect evaluation

9. Integration with other systems

Q: How to integrate with governance systems? A: Integration solutions:

  • Proposal mechanism
  • Vote control
  • Execution delay
  • State synchronization
  • Permission management

Q: How to implement cross-chain upgrades? A: Implementation strategies:

  • Coordinated upgrade
  • State synchronization
  • Data verification
  • Consistency guarantee
  • Exception handling

Released under the MIT License by Vogeb.