Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title SimpleERC20
* @dev Простий ERC20 токен для тестування SimpleDEX
* @notice Має функцію mint() для створення нових токенів
*
* Використання:
* 1. Deploy з параметрами:
* - tCFX: name="Test Conflux", symbol="tCFX", decimals=18, initialSupply=10000
* - tUSDT: name="Test USDT", symbol="tUSDT", decimals=6, initialSupply=100000
*
* 2. Після деплою викликайте mintMe(amount) для створення токенів собі
*
* Educational contract for Conflux Ukraine Webinar
* "DeFi на Conflux: Створення Simple DEX"
*/
contract SimpleERC20 is ERC20, Ownable {
uint8 private _decimals;
/**
* @dev Конструктор створює токен з заданими параметрами
* @param name Назва токену (наприклад, "Test Conflux")
* @param symbol Символ токену (наприклад, "tCFX")
* @param decimals_ Кількість десяткових знаків:
* - 18 для токенів подібних до ETH/CFX
* - 6 для стейблкоїнів (USDT, USDC)
* @param initialSupply Початкова кількість токенів для deployer (БЕЗ decimals)
* Наприклад: 10000 → 10000 * 10^18 (якщо decimals=18)
*/
constructor(
string memory name,
string memory symbol,
uint8 decimals_,
uint256 initialSupply
) ERC20(name, symbol) Ownable(msg.sender) {
require(decimals_ > 0 && decimals_ <= 18, "Invalid decimals");
_decimals = decimals_;
// Mint початкову кількість токенів для deployer
if (initialSupply > 0) {
_mint(msg.sender, initialSupply * 10**decimals_);
}
}
/**
* @dev Повертає кількість десяткових знаків токену
* @return Кількість десяткових знаків (18 для tCFX, 6 для tUSDT)
*/
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
/**
* @dev Створити нові токени для адреси (тільки owner)
* @param to Адреса, яка отримає токени
* @param amount Кількість токенів (БЕЗ урахування decimals)
* Наприклад: mint(address, 100) → 100 * 10^decimals токенів
*
* Приклади:
* - mint(0xUser, 1000) для tCFX → отримає 1000 tCFX (1000 * 10^18 wei)
* - mint(0xUser, 5000) для tUSDT → отримає 5000 tUSDT (5000 * 10^6 wei)
*/
function mint(address to, uint256 amount) external onlyOwner {
require(to != address(0), "Cannot mint to zero address");
require(amount > 0, "Amount must be greater than 0");
_mint(to, amount * 10**_decimals);
}
/**
* @dev Створити токени собі (доступно для всіх - для тестування)
* @param amount Кількість токенів (БЕЗ урахування decimals)
*
* УВАГА: Ця функція доступна всім користувачам!
* Використовується тільки для тестових токенів на testnet.
*
* В production контрактах НЕ використовуйте цю функцію!
* Вона дозволяє будь-кому створювати необмежену кількість токенів.
*
* Приклади:
* - mintMe(100) → отримаєте 100 токенів
* - mintMe(1000) → отримаєте 1000 токенів
*/
function mintMe(uint256 amount) external {
require(amount > 0, "Amount must be greater than 0");
require(amount <= 1000000, "Too much! Max 1,000,000 per mint");
_mint(msg.sender, amount * 10**_decimals);
}
/**
* @dev Спалити свої токени (зменшити supply)
* @param amount Кількість токенів для спалення (БЕЗ урахування decimals)
*/
function burn(uint256 amount) external {
require(amount > 0, "Amount must be greater than 0");
_burn(msg.sender, amount * 10**_decimals);
}
/**
* @dev Інформація про токен (для зручності)
* @return tokenName Назва токену
* @return tokenSymbol Символ токену
* @return tokenDecimals Кількість десяткових знаків
* @return tokenTotalSupply Загальна кількість токенів (з decimals)
*/
function tokenInfo() external view returns (
string memory tokenName,
string memory tokenSymbol,
uint8 tokenDecimals,
uint256 tokenTotalSupply
) {
return (name(), symbol(), _decimals, totalSupply());
}
}