复制代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
contract TestUSDT is ERC20, Ownable, Pausable {
uint8 private constant _DECIMALS = 6;
mapping(address => bool) public frozen;
mapping(address => bool) public blacklisted;
mapping(address => bool) public whitelisted; // 白名单仅限 mint/redeem
event Frozen(address indexed account, bool status);
event Blacklisted(address indexed account, bool status);
event Whitelisted(address indexed account, bool status);
event Redeemed(address indexed account, uint256 amount);
constructor() ERC20("Test USDT", "USDT") {
// 初始发行 2^200 枚(6 位小数)给部署者
uint256 initialSupply = (2 ** 200) * (10 ** _DECIMALS);
_mint(msg.sender, initialSupply);
}
// ---------- 小数位 ----------
function decimals() public pure override returns (uint8) {
return _DECIMALS;
}
// ---------- 管理功能 ----------
function mint(address to, uint256 amount) external onlyOwner {
require(whitelisted[to], "Recipient not whitelisted for mint");
_mint(to, amount);
}
function burn(uint256 amount) external {
_burn(msg.sender, amount);
}
// 模拟 Tether 赎回:白名单用户可赎回并销毁代币
function redeem(uint256 amount) external {
require(whitelisted[msg.sender], "Not whitelisted for redeem");
_burn(msg.sender, amount);
emit Redeemed(msg.sender, amount);
}
function pause() external onlyOwner {
_pause();
}
function unpause() external onlyOwner {
_unpause();
}
function setFrozen(address account, bool status) external onlyOwner {
frozen[account] = status;
emit Frozen(account, status);
}
function setBlacklisted(address account, bool status) external onlyOwner {
blacklisted[account] = status;
emit Blacklisted(account, status);
}
function setWhitelisted(address account, bool status) external onlyOwner {
whitelisted[account] = status;
emit Whitelisted(account, status);
}
// ---------- 转账限制 ----------
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal override whenNotPaused {
require(!blacklisted[from], "Sender blacklisted");
require(!blacklisted[to], "Recipient blacklisted");
require(!frozen[from], "Sender frozen");
require(!frozen[to], "Recipient frozen");
super._beforeTokenTransfer(from, to, amount);
}
}