67 lines
1.8 KiB
Solidity
67 lines
1.8 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
|
|
/**
|
|
* @title TestUSDT
|
|
* @dev 用于测试环境的 USDT 代币合约
|
|
*
|
|
* 特性:
|
|
* - 6 位小数 (与真实 USDT 一致)
|
|
* - 部署者可以自由 mint
|
|
* - 任何人都可以调用 faucet 获取测试代币
|
|
*
|
|
* 部署到:
|
|
* - BSC Testnet (Chain ID: 97)
|
|
* - KAVA Testnet (Chain ID: 2221)
|
|
*/
|
|
contract TestUSDT is ERC20, Ownable {
|
|
uint256 public constant FAUCET_AMOUNT = 1000 * 10**6; // 1000 USDT
|
|
uint256 public constant FAUCET_COOLDOWN = 1 hours;
|
|
|
|
mapping(address => uint256) public lastFaucetTime;
|
|
|
|
constructor() ERC20("Test USDT", "tUSDT") Ownable(msg.sender) {
|
|
// 初始铸造 1,000,000 USDT 给部署者
|
|
_mint(msg.sender, 1_000_000 * 10**6);
|
|
}
|
|
|
|
/**
|
|
* @dev 返回 6 位小数 (与真实 USDT 一致)
|
|
*/
|
|
function decimals() public pure override returns (uint8) {
|
|
return 6;
|
|
}
|
|
|
|
/**
|
|
* @dev Owner 可以铸造任意数量的代币
|
|
*/
|
|
function mint(address to, uint256 amount) external onlyOwner {
|
|
_mint(to, amount);
|
|
}
|
|
|
|
/**
|
|
* @dev 水龙头: 任何人都可以每小时领取 1000 tUSDT
|
|
*/
|
|
function faucet() external {
|
|
require(
|
|
block.timestamp >= lastFaucetTime[msg.sender] + FAUCET_COOLDOWN,
|
|
"Faucet: Please wait 1 hour between requests"
|
|
);
|
|
|
|
lastFaucetTime[msg.sender] = block.timestamp;
|
|
_mint(msg.sender, FAUCET_AMOUNT);
|
|
}
|
|
|
|
/**
|
|
* @dev 批量空投 (Owner only)
|
|
*/
|
|
function airdrop(address[] calldata recipients, uint256 amount) external onlyOwner {
|
|
for (uint256 i = 0; i < recipients.length; i++) {
|
|
_mint(recipients[i], amount);
|
|
}
|
|
}
|
|
}
|