// SPDX-License-Identifier: MIT pragma solidity 0.8.28; import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20Burnable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; import { ERC20Pausable } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol"; import { AccessControl } from "@openzeppelin/contracts/access/AccessControl.sol"; /** * @title ControlledERC20 * @dev 带有转账开关、mint功能和权限管理的ERC20代币合约 * 包含以下功能: * - 转账开关控制 * - 权限管理(管理员、铸造者、暂停者) * - 铸造功能 * - 暂停/恢复功能 */ contract ControlledERC20 is ERC20, ERC20Burnable, ERC20Pausable, AccessControl { // 角色定义 bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant TRANSFER_CONTROLLER_ROLE = keccak256("TRANSFER_CONTROLLER_ROLE"); // 转账开关状态 bool public transferEnabled = true; // 白名单地址(不受转账开关限制) mapping(address => bool) public whitelist; // 事件 event TransferEnabled(bool enabled); event WhitelistUpdated(address indexed account, bool isWhitelisted); constructor( string memory name, string memory symbol, address initialOwner ) ERC20(name, symbol) { // 设置初始角色 _grantRole(DEFAULT_ADMIN_ROLE, initialOwner); _grantRole(MINTER_ROLE, initialOwner); _grantRole(PAUSER_ROLE, initialOwner); _grantRole(TRANSFER_CONTROLLER_ROLE, initialOwner); // 将初始所有者加入白名单 whitelist[initialOwner] = true; emit WhitelistUpdated(initialOwner, true); } /** * @dev 重写transfer函数,添加转账开关检查 */ function transfer(address to, uint256 amount) public virtual override returns (bool) { require(transferEnabled || whitelist[msg.sender] || whitelist[to], "Transfer is disabled"); return super.transfer(to, amount); } /** * @dev 重写transferFrom函数,添加转账开关检查 */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { require(transferEnabled || whitelist[from] || whitelist[to], "Transfer is disabled"); return super.transferFrom(from, to, amount); } /** * @dev 铸造代币(仅限MINTER_ROLE) */ function mint(address to, uint256 amount) external onlyRole(MINTER_ROLE) { _mint(to, amount); } /** * @dev 批量铸造代币(仅限MINTER_ROLE) */ function mintBatch(address[] calldata recipients, uint256[] calldata amounts) external onlyRole(MINTER_ROLE) { require(recipients.length == amounts.length, "Arrays length mismatch"); for (uint256 i = 0; i < recipients.length; i++) { _mint(recipients[i], amounts[i]); } } /** * @dev 暂停合约(仅限PAUSER_ROLE) */ function pause() external onlyRole(PAUSER_ROLE) { _pause(); } /** * @dev 恢复合约(仅限PAUSER_ROLE) */ function unpause() external onlyRole(PAUSER_ROLE) { _unpause(); } /** * @dev 启用/禁用转账(仅限TRANSFER_CONTROLLER_ROLE) */ function setTransferEnabled(bool enabled) external onlyRole(TRANSFER_CONTROLLER_ROLE) { transferEnabled = enabled; emit TransferEnabled(enabled); } /** * @dev 更新白名单(仅限TRANSFER_CONTROLLER_ROLE) */ function updateWhitelist(address account, bool whitelisted) external onlyRole(TRANSFER_CONTROLLER_ROLE) { whitelist[account] = whitelisted; emit WhitelistUpdated(account, whitelisted); } /** * @dev 批量更新白名单(仅限TRANSFER_CONTROLLER_ROLE) */ function updateWhitelistBatch(address[] calldata accounts, bool[] calldata whitelisted) external onlyRole(TRANSFER_CONTROLLER_ROLE) { require(accounts.length == whitelisted.length, "Arrays length mismatch"); for (uint256 i = 0; i < accounts.length; i++) { whitelist[accounts[i]] = whitelisted[i]; emit WhitelistUpdated(accounts[i], whitelisted[i]); } } /** * @dev 检查地址是否在白名单中 */ function isWhitelisted(address account) external view returns (bool) { return whitelist[account]; } /** * @dev 重写_update函数以支持暂停功能 */ function _update(address from, address to, uint256 value) internal override(ERC20, ERC20Pausable) { super._update(from, to, value); } /** * @dev 重写supportsInterface函数以支持AccessControl */ function supportsInterface(bytes4 interfaceId) public view override(AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } }