Tokens Contract#
L Token#
Overview#
L Token is a token contract based on an upgraded ERC20 standard, implementing the following core functionalities:
Token Minting and Burning: Control minting and burning through role-based permissions
User Claim Mechanism: Supports users claiming tokens through whitelist and receiving ERB rewards
Maximum Supply Limit: Total supply cannot exceed 1 trillion tokens
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:
Check if msg.value is valid (but msg.value is unsigned integer, this check is redundant)
Ensure contract has sufficient ERB balance for transfer
Prevent zero address calls or receipts
Ensure total supply doesn’t exceed MAX_SUPPLY
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:
Token Distribution: Manages tokens for different purposes through linear vesting and pre-allocation mechanisms
Access Control: Role-based access control (inherited from Auth contract)
Claim Mechanism: Supports users claiming tokens through whitelist and receiving ERB rewards
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#
- Address Validation:
Check zero address (InvalidZeroAddress)
Verify caller validity (CallerIsZeroAddress)
- Supply Limits:
Total claims not exceeding BONDING_SUPPLY
Linear release not exceeding total allocation
- 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#
Deploy contract and call initialize function:
LLAToken.initialize(admin, pauser, minter, upgrader);
Call mint function to mint tokens:
LLAToken.mint(userAddress, 1000 * 1e18); // Mint 1000 LLA
Scenario: Pausing Token Trading#
Call pause function to pause contract:
LLAToken.pause(); // Must be called by PAUSER_ROLE
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.
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