Tokens Contract#

L Token#

Overview#

L Token is a token contract based on an upgraded ERC20 standard, implementing the following core functionalities:

  1. Token Minting and Burning: Control minting and burning through role-based permissions

  2. User Claim Mechanism: Supports users claiming tokens through whitelist and receiving ERB rewards

  3. Maximum Supply Limit: Total supply cannot exceed 1 trillion tokens

  4. Permission Control: Role-based access control (inherited from Auth contract)

Core Constants and Variables#

Maximum Supply#

uint256 public constant MAX_SUPPLY = 100000000000 * 10 ** 18; // 1 trillion tokens (18 decimals)

Error Definitions#

error InvalidZeroAddress(); // Invalid zero address
error CallerIsZeroAddress(); // Caller is zero address
error InvalidErbAmt(uint256 erbAmt); // Invalid ERB amount (msg.value is negative)
error ExceedsMaxSupply(uint256 totalSupply, uint256 lAmt); // Total supply exceeds maximum
error InsufficientERBBalance(address from, uint256 balance); // Insufficient ERB balance in contract

Core Events#

event Claim(
    address indexed recipient, // Recipient address
    uint256 lAmt,             // Amount of L tokens claimed
    uint256 erbAmt            // Amount of ERB transferred (msg.value)
);

Core Function Details#

1. Initialization Function#

function initialize(address superOwner) public initializer {
    super.initializeAuth(superOwner); // Initialize Auth contract's super admin
    __ERC20_init("L", "L");           // Initialize ERC20 token name and symbol
}
  • Requires super admin address

  • Initializes ERC20 token parameters

2. Whitelist Modifier#

modifier onlyWhitelisted() {
    require(hasRole(WHITELISTED_ROLE, msg.sender), "Not whitelisted");
    _;
}
  • Only allows addresses with WHITELISTED_ROLE to call protected functions

3. Minting Function#

function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
    _mint(to, amount);
}
  • Requires MINTER_ROLE

  • No supply limit check (may bypass MAX_SUPPLY)

4. Burning Function#

function burn(address from, uint256 amount) public onlyRole(BURNER_ROLE) {
    _burn(from, amount);
}
  • Requires BURNER_ROLE

5. User Claim Function#

  • Must be called through whitelist

  • Key Logic:
    1. Check if msg.value is valid (but msg.value is unsigned integer, this check is redundant)

    2. Ensure contract has sufficient ERB balance for transfer

    3. Prevent zero address calls or receipts

    4. Ensure total supply doesn’t exceed MAX_SUPPLY

    5. Mint tokens and transfer user’s paid ERB

XL Token#

Overview#

XL Token is a token contract based on an upgraded ERC20 standard that implements the following core functionalities:

  1. Token Distribution: Manages tokens for different purposes through linear vesting and pre-allocation mechanisms

  2. Access Control: Role-based access control (inherited from Auth contract)

  3. Claim Mechanism: Supports users claiming tokens through whitelist and receiving ERB rewards

  4. Time Release: Sets linear vesting schedules for ecosystem fund, strategic financing, and team tokens

Core Constants Definition#

Token Parameters#

uint256 public constant MAX_SUPPLY = 10_000_000_000 * 10 ** 18; // 10 billion tokens (18 decimals)

Time Parameters#

uint256 public constant THREE_YEARS = 3 * 365 days;
uint256 public constant FIVE_YEARS = 5 * 365 days;
uint256 public constant MONTH = 30 days;
uint256 public constant QUARTER = 90 days;

Token Distribution Structure#

Pre-allocation Addresses#

address public taskIncentiveAddress; // Task incentive address
address public ecosystemFundAddress; // Ecosystem fund address
address public strategicFinanceAddress; // Strategic finance address
address public teamAddress; // Team address
address public marketingAddress; // Marketing address

Supply Distribution#

// 62% Bonding curve release
uint256 public constant BONDING_SUPPLY = 6_200_000_000e18;

// 8% Pre-allocation (instant unlock)
uint256 public constant TASK_INCENTIVE_SUPPLY = 800_000_000e18;

// 12% Linear vesting (5 years, monthly release)
uint256 public constant ECOSYSTEM_FUND_SUPPLY = 1_200_000_000e18;

// 10% Linear vesting (3 years, monthly release)
uint256 public constant STRATEGIC_FINANCE_SUPPLY = 1_000_000_000e18;

// 6% Linear vesting (5 years, quarterly release)
uint256 public constant TEAM_SUPPLY = 600_000_000e18;

// 2% Pre-allocation (instant unlock)
uint256 public constant MARKETING_SUPPLY = 200_000_000e18;

Core Variables#

Timestamp Records#

uint256 public ecosystemStartTime; // Ecosystem release start time
uint256 public strategicFinanceStartTime; // Strategic finance start time
uint256 public teamStartTime; // Team token start time

Released Amount Records#

uint256 public ecosystemReleased; // Released ecosystem tokens
uint256 public strategicFinanceReleased; // Released strategic finance tokens
uint256 public teamReleased; // Released team tokens

Total Claim Records#

uint256 public totalClaimed; // Total claimed bonding tokens

Error Definitions#

error InvalidZeroAddress(); // Invalid zero address
error CallerIsZeroAddress(); // Caller is zero address
error ExceedsClaimSupply(uint256 claimed, uint256 lAmt); // Exceeds claim supply
error InsufficientERBBalance(address from, uint256 balance); // Insufficient ERB balance

Core Events#

event Claim(
    address indexed recipient, // Recipient address
    uint256 indexed xlAmt,    // Claimed XL amount
    uint256 indexed erbAmt    // Transferred ERB amount
);

Core Functions Explained#

1. Initialize Function#

function initialize(...) public initializer {
    // Initialize access control
    super.initializeAuth(_superOwner);

    // Initialize ERC20 token parameters
    __ERC20_init("XL", "XL");

    // Set pre-allocation addresses
    taskIncentiveAddress = _taskIncentiveAddress;
    ecosystemFundAddress = _ecosystemFundAddress;
    strategicFinanceAddress = _strategicFinanceAddress;
    teamAddress = _teamAddress;
    marketingAddress = _marketingAddress;

    // Pre-allocate tokens
    _mint(taskIncentiveAddress, TASK_INCENTIVE_SUPPLY);
    _mint(marketingAddress, MARKETING_SUPPLY);

    // Set initial timestamps
    ecosystemStartTime = block.timestamp;
    strategicFinanceStartTime = block.timestamp;
    teamStartTime = block.timestamp;
}
  • Requires super admin and other address parameters

  • Pre-allocates 8% and 2% of tokens

  • Initializes release timestamps to contract deployment time

2. Claim Function#

function claim(address payable recipient, uint256 _xlAmt)
    external payable onlyWhitelisted {
    // Safety checks
    if (address(this).balance < msg.value) revert InsufficientERBBalance(...);
    if (recipient == address(0)) revert InvalidZeroAddress();
    if (msg.sender == address(0)) revert CallerIsZeroAddress();
    if (totalClaimed + _xlAmt > BONDING_SUPPLY) revert ExceedsClaimSupply(...);

    // Claim logic
    totalClaimed += _xlAmt;
    _mint(recipient, _xlAmt);

    // Transfer ERB
    recipient.transfer(msg.value);

    // Emit event
    emit Claim(recipient, _xlAmt, msg.value);
}
  • Must be called through whitelist

  • Checks address validity and total claim limit

  • Transfers user-paid ERB (via msg.value)

  • Emits Claim event to record claim details

3. Linear Release Function#

function releaseLinear() external onlySuperOwner {
    // Calculate tokens to release for each part
    uint256 ecosystemToRelease = calculateLinearRelease(
        ECOSYSTEM_FUND_SUPPLY, FIVE_YEARS, ecosystemStartTime,
        ecosystemReleased, MONTH
    );

    // Same calculation for strategic finance and team tokens
    // ...

    // Mint and update records
    if (ecosystemToRelease > 0) {
        ecosystemReleased += ecosystemToRelease;
        _mint(ecosystemFundAddress, ecosystemToRelease);
    }
    // Same for other parts
}
  • Only callable by super admin

  • Uses calculateLinearRelease to calculate release amount

  • Releases tokens monthly/quarterly

4. Linear Release Calculation Function#

function calculateLinearRelease(
    uint256 total,
    uint256 duration,
    uint256 startTime,
    uint256 alreadyReleased,
    uint256 releaseInterval
) internal view returns (uint256) {
    // Calculate elapsed time
    uint256 elapsedTime = block.timestamp - startTime;

    // Calculate total and elapsed periods
    uint256 totalPeriods = duration / releaseInterval;
    uint256 elapsedPeriods = elapsedTime / releaseInterval;

    // Calculate total amount to release
    uint256 totalToRelease = (total * elapsedPeriods) / totalPeriods;

    // Ensure not exceeding total supply
    if (totalToRelease > total) totalToRelease = total;

    // Calculate amount for this release
    return totalToRelease - alreadyReleased;
}
  • Calculates released periods based on time

  • Calculates tokens to be released proportionally

  • Returns remaining amount for this release

Access Control#

Role Management#

  • MINTER_ROLE: Allows calling mint function

  • BURNER_ROLE: Allows calling burn function

  • WHITELISTED_ROLE: Allows calling claim function

  • SUPER_OWNER: Allows calling releaseLinear and setAddresses

Modifiers#

modifier onlyWhitelisted() {
    require(hasRole(WHITELISTED_ROLE, msg.sender), "Not whitelisted");
    _;
}

Security Measures#

  1. Address Validation:
    • Check zero address (InvalidZeroAddress)

    • Verify caller validity (CallerIsZeroAddress)

  2. Supply Limits:
    • Total claims not exceeding BONDING_SUPPLY

    • Linear release not exceeding total allocation

  3. Fund Security:
    • Check contract balance sufficient for ERB transfer

    • Use payable function for Ethereum transfers

Version Information#

function getVersion() public pure returns (string memory) {
    return "1.0.0";
}

LLA Token#

Contract Overview#

LLA Token is an upgradeable ERC20 token contract based on OpenZeppelin, supporting the following core functions:

  • Role-based Access Control: Manages ADMIN_ROLE, PAUSER_ROLE, MINTER_ROLE, UPGRADER_ROLE through AccessControl

  • Upgradeability: Implements secure upgrades through UUPS pattern

  • Token Pausability: Supports global pause/unpause of token transfers

  • Token Minting and Burning: Supports controlled minting and burning

  • Fixed Total Supply: Set total supply at 100,000,000 LLA

Core Variables and Configuration#

Role Definitions#

bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");

Other Configurations#

string public constant version = "v1.0";
uint256 public constant TOTAL_SUPPLY = 100_0000_0000 * 1e18; // 100,000,000 LLA

Core Functions Explained#

1. Initialization Function#

function initialize(
    address defaultAdmin,
    address pauser,
    address minter,
    address upgrader
) public initializer {
    if (defaultAdmin == address(0)) revert InvalidAddress(defaultAdmin);
    // ... other address validations
    __ERC20_init("LLA", "LLA");
    __ERC20Burnable_init();
    __ERC20Pausable_init();
    __AccessControl_init();
    __UUPSUpgradeable_init();
    _grantRole(ADMIN_ROLE, defaultAdmin);
    _grantRole(PAUSER_ROLE, pauser);
    _grantRole(MINTER_ROLE, minter);
    _grantRole(UPGRADER_ROLE, upgrader);
}
  • Purpose: Initialize contract and assign roles

  • Key Points:

    • Validate all address legitimacy

    • Initialize parent contracts (ERC20, Access Control, Upgradeable)

    • Grant initial role permissions

2. Token Minting#

function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
    if (amount == 0) revert InvalidAmount(amount);
    if (to == address(0)) revert InvalidAddress(to);
    _mint(to, amount);
}
  • Purpose: Mint new tokens

  • Restrictions:

    • Only callable by MINTER_ROLE

    • Prevent minting to zero address or zero amount

3. Pause and Unpause#

function pause() public onlyRole(PAUSER_ROLE) {
    _pause();
}

function unpause() public onlyRole(PAUSER_ROLE) {
    _unpause();
}
  • Purpose: Global pause/unpause of token transfers

  • Impact:

    • No transfers or approvals during pause

4. Token Burning#

function burn(uint256 amount) public override {
    if (amount == 0) revert InvalidAmount(amount);
    _burn(msg.sender, amount);
}
  • Purpose: Burn user’s own tokens

  • Enhancement:

    • Validate burn amount is not zero

5. Upgrade Control#

function _authorizeUpgrade(
    address _newImplementation
) internal view override onlyRole(UPGRADER_ROLE) {
    if (_newImplementation == address(0)) revert InvalidAddress(_newImplementation);
}
  • Purpose: Authorize upgrade to new implementation contract

  • Restrictions:

    • Only callable by UPGRADER_ROLE

    • Prevent upgrade to zero address

6. Role Management#

function addRole(bytes32 role, address account) external onlyRole(ADMIN_ROLE) {
    _grantRole(role, account);
}

function revokeRole(bytes32 role, address account) public override onlyRole(ADMIN_ROLE) {
    _revokeRole(role, account);
}
  • Purpose: Admin management of role permissions

  • Permissions:

    • Only ADMIN_ROLE can add/revoke roles

7. Custom Errors#

error InvalidAddress(address addr);
error InvalidAmount(uint amount);
  • Usage: Enhance error message readability

Function Workflows#

Scenario: Minting and Distributing Tokens#

  1. Deploy contract and call initialize function:

LLAToken.initialize(admin, pauser, minter, upgrader);
  1. Call mint function to mint tokens:

LLAToken.mint(userAddress, 1000 * 1e18); // Mint 1000 LLA

Scenario: Pausing Token Trading#

  1. Call pause function to pause contract:

LLAToken.pause(); // Must be called by PAUSER_ROLE
  1. No transfers or approvals possible during pause

Events and Errors#

Events#

  • ERC20 Standard Events: Transfer, Approval

  • Access Control Events: RoleGranted, RoleRevoked

Errors#

error InvalidAddress(address addr);
error InvalidAmount(uint amount);

LLAX Token#

Contract Overview#

LLAXToken is an ERC20 token based on the OpenZeppelin upgradeable contract, supporting upgradability, pausing, burning, and role-based access control.

The contract uses multi-role permission management and is suitable for mainstream DeFi, DAO, and Web3 project scenarios.

Main Features#

  • Upgradeable: UUPS upgrade pattern

  • Access Control: Multi-role permission management based on AccessControl

  • Pausable: Supports emergency pause/resume

  • Burnable: Supports token burning

  • Total Supply Cap: Maximum supply limit

  • Events & Errors: Custom errors and events for tracking and debugging

Role Description#

Role Name

Identifier

Permission Description

Admin

ADMIN_ROLE

Grant/revoke roles, manage contract

Pauser

PAUSER_ROLE

Pause/resume the contract

Minter

MINTER_ROLE

Mint new tokens

Upgrader

UPGRADER_ROLE

Upgrade the contract

Constants#

  • string public constant version = “v1.0”; Contract version

  • uint256 public constant TOTAL_SUPPLY = 6_5000_0000 * 1e18; Maximum token supply (650 million)

Custom Errors#

  • InvalidAddress(address addr) Thrown when an invalid address is provided

  • InvalidAmount(uint amount) Thrown when an invalid amount is provided

Main Functions#

Initialization#

function initialize(
    address defaultAdmin,
    address pauser,
    address minter,
    address upgrader
) public initializer
  • Initializes the contract, assigns roles, and sets token name and symbol.

Pause and Resume#

function pause() public onlyRole(PAUSER_ROLE)
function unpause() public onlyRole(PAUSER_ROLE)
  • Only callable by PAUSER_ROLE, pauses/resumes all transfer-related operations.

Minting and Burning#

function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE)
function burn(uint256 amount) public override
  • mint: Only callable by MINTER_ROLE, mints new tokens to the specified address, and will not exceed the maximum supply.

  • burn: Burns tokens from the caller’s account.

Upgrade Authorization#

function _authorizeUpgrade(address _newImplementation) internal view override onlyRole(UPGRADER_ROLE)
  • Only callable by UPGRADER_ROLE, authorizes contract upgrade.

Role Management#

function addRole(bytes32 role, address account) external onlyRole(ADMIN_ROLE)
function revokeRole(bytes32 role, address account) public override onlyRole(ADMIN_ROLE)
  • Admin can assign/revoke roles for any address.

Approve Operation#

function approve(address spender, uint256 amount) public override whenNotPaused returns (bool)
  • Can only approve when not paused.

Internal Methods#

function _update(address from, address to, uint256 value) internal override(ERC20Upgradeable, ERC20PausableUpgradeable)
  • Handles internal state updates during transfers, compatible with pause logic.

Security Notes#

  • All sensitive operations are permission-controlled

  • Minting, burning, and upgrading are strictly checked

  • Supports contract pausing for emergency handling

  • Hard cap on total supply to prevent over-issuance

Deployment and Upgrade#

  • Recommended to use OpenZeppelin Upgrades plugin for deployment and upgrade

  • Initialization parameters must provide all role addresses and none can be zero address

Typical Usage Examples#

// Mint tokens
llaxToken.mint(user, 1000 * 1e18);

// Burn tokens
llaxToken.burn(500 * 1e18);

// Pause the contract
llaxToken.pause();

// Grant role
llaxToken.addRole(llaxToken.MINTER_ROLE(), newMinter);

Version Info#

  • Contract version: v1.0

  • Compatible with OpenZeppelin Contracts ^5.0.0

  • Solidity version: ^0.8.28

License#

MIT License