Description:
ERC20 token contract with Mintable, Burnable, Pausable, Factory capabilities. Standard implementation for fungible tokens on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"Contract/Usdt.sol": {
"content": "// SPDX-License-Identifier: MIT\r
// Compatible with Modern Solidity Contracts\r
pragma solidity ^0.8.27;\r
\r
/**\r
* @title TetherUSDT - Clean USDT Implementation\r
* @dev Complete USDT implementation with Flash Loans, Pausable, and Owner Management\r
* Features: ERC20, Flash Loans (EIP-3156), Pausable, Mint/Burn, Fee Management\r
* Ready for Ethereum Mainnet Deployment\r
*/\r
\r
// ==================================================================================\r
// INTERFACES\r
// ==================================================================================\r
\r
interface IERC20 {\r
function totalSupply() external view returns (uint256);\r
function balanceOf(address account) external view returns (uint256);\r
function transfer(address to, uint256 value) external returns (bool);\r
function allowance(address owner, address spender) external view returns (uint256);\r
function approve(address spender, uint256 value) external returns (bool);\r
function transferFrom(address from, address to, uint256 value) external returns (bool);\r
\r
event Transfer(address indexed from, address indexed to, uint256 value);\r
event Approval(address indexed owner, address indexed spender, uint256 value);\r
}\r
\r
interface IERC3156FlashBorrower {\r
function onFlashLoan(\r
address initiator,\r
address token,\r
uint256 amount,\r
uint256 fee,\r
bytes calldata data\r
) external returns (bytes32);\r
}\r
\r
interface IERC3156FlashLender {\r
function maxFlashLoan(address token) external view returns (uint256);\r
function flashFee(address token, uint256 amount) external view returns (uint256);\r
function flashLoan(\r
IERC3156FlashBorrower receiver,\r
address token,\r
uint256 amount,\r
bytes calldata data\r
) external returns (bool);\r
}\r
\r
// ==================================================================================\r
// MAIN CONTRACT\r
// ==================================================================================\r
\r
contract TetherUSDT is IERC20, IERC3156FlashLender {\r
\r
// ==================================================================================\r
// STATE VARIABLES (OPTIMIZED FOR GAS)\r
// ==================================================================================\r
\r
// Pack small variables together to save storage slots\r
struct ContractState {\r
address owner; // 20 bytes\r
bool paused; // 1 byte\r
uint8 decimals; // 1 byte\r
// 10 bytes remaining in slot\r
}\r
\r
struct FeeConfig {\r
uint256 basisPointsRate; // 32 bytes - slot 1\r
uint256 maximumFee; // 32 bytes - slot 2 \r
uint256 flashLoanFeeBasisPoints; // 32 bytes - slot 3\r
}\r
\r
ContractState public state;\r
FeeConfig public fees;\r
\r
string public constant NAME = "Tether USDT";\r
string public constant SYMBOL = "USDT";\r
uint256 private _totalSupply;\r
\r
// Constants (no storage cost)\r
bytes32 private constant CALLBACK_SUCCESS = keccak256("ERC3156FlashBorrower.onFlashLoan");\r
uint256 private constant MAX_SETTABLE_BASIS_POINTS = 20;\r
uint256 private constant MAX_SETTABLE_FEE = 50;\r
uint256 private constant NOT_ENTERED = 1;\r
uint256 private constant ENTERED = 2;\r
uint256 private _status;\r
\r
// Mappings\r
mapping(address => uint256) private _balances;\r
mapping(address => mapping(address => uint256)) private _allowances;\r
mapping(address => bool) public isBlackListed;\r
\r
// ==================================================================================\r
// EVENTS\r
// ==================================================================================\r
\r
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\r
event Pause();\r
event Unpause();\r
event AddedBlackList(address indexed user);\r
event RemovedBlackList(address indexed user);\r
event DestroyedBlackFunds(address indexed blackListedUser, uint256 balance);\r
event Issue(uint256 amount);\r
event Redeem(uint256 amount);\r
event Params(uint256 feeBasisPoints, uint256 maxFee);\r
event FlashLoan(address indexed initiator, address indexed receiver, uint256 amount, uint256 fee);\r
event FlashLoanFeeUpdated(uint256 newFee);\r
\r
// Additional transfer events\r
event TransferWithData(address indexed from, address indexed to, uint256 value, bytes data);\r
event EmergencyTransfer(address indexed from, address indexed to, uint256 value);\r
\r
// ==================================================================================\r
// MODIFIERS\r
// ==================================================================================\r
\r
modifier onlyOwner() {\r
require(msg.sender == state.owner, "!owner");\r
_;\r
}\r
\r
modifier whenNotPaused() {\r
require(!state.paused, "paused");\r
_;\r
}\r
\r
modifier whenPaused() {\r
require(state.paused, "!paused");\r
_;\r
}\r
\r
modifier nonReentrant() {\r
require(_status != ENTERED, "reentrant");\r
_status = ENTERED;\r
_;\r
_status = NOT_ENTERED;\r
}\r
\r
// ==================================================================================\r
// CONSTRUCTOR\r
// ==================================================================================\r
\r
constructor(address recipient, address initialOwner) {\r
state.owner = initialOwner;\r
state.paused = false;\r
state.decimals = 6;\r
fees.basisPointsRate = 0;\r
fees.maximumFee = 0;\r
fees.flashLoanFeeBasisPoints = 9; // 0.09% fee\r
_status = NOT_ENTERED;\r
_mint(recipient, 1000000000 * 10 ** state.decimals);\r
\r
emit OwnershipTransferred(address(0), initialOwner);\r
}\r
\r
// ==================================================================================\r
// OWNERSHIP FUNCTIONS\r
// ==================================================================================\r
\r
function transferOwnership(address newOwner) public onlyOwner {\r
require(newOwner != address(0), "zero addr");\r
emit OwnershipTransferred(state.owner, newOwner);\r
state.owner = newOwner;\r
}\r
\r
// ==================================================================================\r
// PAUSABLE FUNCTIONS\r
// ==================================================================================\r
\r
function pause() public onlyOwner whenNotPaused {\r
state.paused = true;\r
emit Pause();\r
}\r
\r
function unpause() public onlyOwner whenPaused {\r
state.paused = false;\r
emit Unpause();\r
}\r
\r
// ==================================================================================\r
// ERC20 FUNCTIONS\r
// ==================================================================================\r
\r
function name() public pure returns (string memory) {\r
return NAME;\r
}\r
\r
function symbol() public pure returns (string memory) {\r
return SYMBOL;\r
}\r
\r
function decimals() public view returns (uint8) {\r
return state.decimals;\r
}\r
\r
function totalSupply() public view override returns (uint256) {\r
return _totalSupply;\r
}\r
\r
function balanceOf(address account) public view override returns (uint256) {\r
return _balances[account];\r
}\r
\r
function transfer(address to, uint256 value) public override whenNotPaused returns (bool) {\r
require(!isBlackListed[msg.sender], "blacklisted");\r
_transfer(msg.sender, to, value);\r
return true;\r
}\r
\r
function allowance(address owner_, address spender) public view override returns (uint256) {\r
return _allowances[owner_][spender];\r
}\r
\r
function approve(address spender, uint256 value) public override whenNotPaused returns (bool) {\r
_approve(msg.sender, spender, value);\r
return true;\r
}\r
\r
function transferFrom(address from, address to, uint256 value) public override whenNotPaused returns (bool) {\r
require(!isBlackListed[from], "blacklisted");\r
\r
uint256 currentAllowance = _allowances[from][msg.sender];\r
require(currentAllowance >= value, "low allowance");\r
\r
_transfer(from, to, value);\r
_approve(from, msg.sender, currentAllowance - value);\r
\r
return true;\r
}\r
\r
// ==================================================================================\r
// ADDITIONAL TRANSFER OPTIONS\r
// ==================================================================================\r
\r
/**\r
* @dev Batch transfer to multiple recipients\r
* @param recipients Array of recipient addresses\r
* @param values Array of transfer amounts\r
*/\r
function batchTransfer(address[] calldata recipients, uint256[] calldata values) \r
public \r
whenNotPaused \r
returns (bool) \r
{\r
uint256 length = recipients.length;\r
require(length == values.length && length > 0, "invalid arrays");\r
require(!isBlackListed[msg.sender], "blacklisted");\r
\r
uint256 totalAmount;\r
// Gas optimized loop using unchecked arithmetic\r
unchecked {\r
for (uint256 i; i < length; ++i) {\r
totalAmount += values[i];\r
}\r
}\r
\r
require(_balances[msg.sender] >= totalAmount, "low balance");\r
\r
unchecked {\r
for (uint256 i; i < length; ++i) {\r
address recipient = recipients[i];\r
require(recipient != address(0) && !isBlackListed[recipient], "invalid recipient");\r
_transfer(msg.sender, recipient, values[i]);\r
}\r
}\r
\r
return true;\r
}\r
\r
/**\r
* @dev Transfer with additional data\r
* @param to Recipient address\r
* @param value Transfer amount\r
* @param data Additional data\r
*/\r
function transferWithData(address to, uint256 value, bytes calldata data) \r
public \r
whenNotPaused \r
returns (bool) \r
{\r
require(!isBlackListed[msg.sender], "blacklisted");\r
_transfer(msg.sender, to, value);\r
\r
emit TransferWithData(msg.sender, to, value, data);\r
return true;\r
}\r
\r
/**\r
* @dev Safe transfer that checks if recipient can receive tokens\r
* @param to Recipient address\r
* @param value Transfer amount\r
*/\r
function safeTransfer(address to, uint256 value) \r
public \r
whenNotPaused \r
returns (bool) \r
{\r
require(!isBlackListed[msg.sender], "blacklisted");\r
require(to != address(this), "cannot transfer to contract");\r
\r
// Check if recipient is a contract\r
if (to.code.length > 0) {\r
// For contracts, ensure they can receive tokens by checking they're not paused\r
// This is a basic safety check - in production you might want to implement\r
// a more sophisticated receiver check\r
require(!isBlackListed[to], "recipient blacklisted");\r
}\r
\r
_transfer(msg.sender, to, value);\r
return true;\r
}\r
\r
/**\r
* @dev Transfer multiple amounts to the same recipient\r
* @param to Recipient address\r
* @param values Array of amounts to transfer\r
*/\r
function multiTransfer(address to, uint256[] calldata values) \r
public \r
whenNotPaused \r
returns (bool) \r
{\r
require(!isBlackListed[msg.sender] && to != address(0) && !isBlackListed[to], "invalid transfer");\r
\r
uint256 length = values.length;\r
require(length > 0, "empty array");\r
\r
unchecked {\r
for (uint256 i; i < length; ++i) {\r
uint256 value = values[i];\r
require(value > 0, "zero amount");\r
_transfer(msg.sender, to, value);\r
}\r
}\r
\r
return true;\r
}\r
\r
/**\r
* @dev Emergency transfer function for owner to move funds\r
* @param from Source address\r
* @param to Destination address \r
* @param value Amount to transfer\r
*/\r
function emergencyTransfer(address from, address to, uint256 value) \r
public \r
onlyOwner \r
returns (bool) \r
{\r
require(from != address(0), "zero from");\r
require(to != address(0), "zero to");\r
require(_balances[from] >= value, "low balance");\r
\r
_balances[from] -= value;\r
_balances[to] += value;\r
\r
emit Transfer(from, to, value);\r
emit EmergencyTransfer(from, to, value);\r
return true;\r
}\r
\r
/**\r
* @dev Transfer with approval in one transaction\r
* @param to Recipient address\r
* @param value Transfer amount\r
* @param spender Address to approve\r
* @param approvalAmount Amount to approve\r
*/\r
function transferAndApprove(\r
address to, \r
uint256 value, \r
address spender, \r
uint256 approvalAmount\r
) \r
public \r
whenNotPaused \r
returns (bool) \r
{\r
require(!isBlackListed[msg.sender], "blacklisted");\r
\r
// Execute transfer\r
_transfer(msg.sender, to, value);\r
\r
// Set approval\r
_approve(msg.sender, spender, approvalAmount);\r
\r
return true;\r
}\r
\r
// ==================================================================================\r
// TRANSFER UTILITY FUNCTIONS\r
// ==================================================================================\r
\r
/**\r
* @dev Check if an address can receive transfers\r
* @param account Address to check\r
* @return canReceive True if address can receive transfers\r
*/\r
function canReceiveTransfer(address account) public view returns (bool canReceive) {\r
return account != address(0) && !isBlackListed[account] && !state.paused;\r
}\r
\r
/**\r
* @dev Check if an address can send transfers\r
* @param account Address to check\r
* @return canSend True if address can send transfers\r
*/\r
function canSendTransfer(address account) public view returns (bool canSend) {\r
return account != address(0) && !isBlackListed[account] && !state.paused;\r
}\r
\r
/**\r
* @dev Get transfer limits for an address\r
* @param account Address to check\r
* @return maxTransfer Maximum amount that can be transferred\r
*/\r
function getTransferLimit(address account) public view returns (uint256 maxTransfer) {\r
if (!canSendTransfer(account)) {\r
return 0;\r
}\r
return _balances[account];\r
}\r
\r
/**\r
* @dev Simulate transfer to check if it would succeed\r
* @param from Source address\r
* @param to Destination address\r
* @param value Amount to transfer\r
* @return success True if transfer would succeed\r
* @return reason Failure reason if transfer would fail\r
*/\r
function simulateTransfer(address from, address to, uint256 value) \r
public \r
view \r
returns (bool success, string memory reason) \r
{\r
if (state.paused) {\r
return (false, "contract paused");\r
}\r
if (from == address(0)) {\r
return (false, "zero from address");\r
}\r
if (to == address(0)) {\r
return (false, "zero to address");\r
}\r
if (isBlackListed[from]) {\r
return (false, "sender blacklisted");\r
}\r
if (isBlackListed[to]) {\r
return (false, "recipient blacklisted");\r
}\r
if (_balances[from] < value) {\r
return (false, "insufficient balance");\r
}\r
if (value == 0) {\r
return (false, "zero amount");\r
}\r
\r
return (true, "transfer would succeed");\r
}\r
\r
// ==================================================================================\r
// INTERNAL ERC20 FUNCTIONS\r
// ==================================================================================\r
\r
function _transfer(address from, address to, uint256 value) internal {\r
require(from != address(0) && to != address(0), "zero addr");\r
\r
uint256 fromBalance = _balances[from];\r
require(fromBalance >= value, "low balance");\r
\r
uint256 fee = calcFee(value);\r
uint256 sendAmount;\r
\r
unchecked {\r
sendAmount = value - fee;\r
_balances[from] = fromBalance - value;\r
_balances[to] += sendAmount;\r
}\r
\r
if (fee > 0) {\r
_balances[state.owner] += fee;\r
emit Transfer(from, state.owner, fee);\r
}\r
\r
emit Transfer(from, to, sendAmount);\r
}\r
\r
function _mint(address to, uint256 value) internal {\r
require(to != address(0), "zero addr");\r
unchecked {\r
_totalSupply += value;\r
_balances[to] += value;\r
}\r
emit Transfer(address(0), to, value);\r
}\r
\r
function _burn(address from, uint256 value) internal {\r
require(from != address(0), "zero addr");\r
\r
uint256 fromBalance = _balances[from];\r
require(fromBalance >= value, "low balance");\r
\r
unchecked {\r
_balances[from] = fromBalance - value;\r
_totalSupply -= value;\r
}\r
emit Transfer(from, address(0), value);\r
}\r
\r
function _approve(address owner_, address spender, uint256 value) internal {\r
require(owner_ != address(0), "zero owner");\r
require(spender != address(0), "zero spender");\r
_allowances[owner_][spender] = value;\r
emit Approval(owner_, spender, value);\r
}\r
\r
// ==================================================================================\r
// MINT/BURN FUNCTIONS\r
// ==================================================================================\r
\r
function mint(address to, uint256 amount) public onlyOwner {\r
_mint(to, amount);\r
emit Issue(amount);\r
}\r
\r
function burn(uint256 amount) public onlyOwner {\r
_burn(state.owner, amount);\r
emit Redeem(amount);\r
}\r
\r
// ==================================================================================\r
// BLACKLIST FUNCTIONS\r
// ==================================================================================\r
\r
function addBlackList(address user) public onlyOwner {\r
isBlackListed[user] = true;\r
emit AddedBlackList(user);\r
}\r
\r
function removeBlackList(address user) public onlyOwner {\r
isBlackListed[user] = false;\r
emit RemovedBlackList(user);\r
}\r
\r
function destroyBlackFunds(address blackListedUser) public onlyOwner {\r
require(isBlackListed[blackListedUser], "not blacklisted");\r
uint256 dirtyFunds = _balances[blackListedUser];\r
_balances[blackListedUser] = 0;\r
_totalSupply -= dirtyFunds;\r
emit DestroyedBlackFunds(blackListedUser, dirtyFunds);\r
emit Transfer(blackListedUser, address(0), dirtyFunds);\r
}\r
\r
// ==================================================================================\r
// FEE MANAGEMENT\r
// ==================================================================================\r
\r
function calcFee(uint256 value) public view returns (uint256) {\r
uint256 fee = (value * fees.basisPointsRate) / 10000;\r
if (fee > fees.maximumFee) {\r
fee = fees.maximumFee;\r
}\r
return fee;\r
}\r
\r
function setParams(uint256 newBasisPoints, uint256 newMaxFee) public onlyOwner {\r
require(newBasisPoints < MAX_SETTABLE_BASIS_POINTS, "fee too high");\r
require(newMaxFee < MAX_SETTABLE_FEE, "max fee too high");\r
\r
fees.basisPointsRate = newBasisPoints;\r
fees.maximumFee = newMaxFee * (10 ** state.decimals);\r
\r
emit Params(fees.basisPointsRate, fees.maximumFee);\r
}\r
\r
// ==================================================================================\r
// FLASH LOAN FUNCTIONS (EIP-3156)\r
// ==================================================================================\r
\r
function maxFlashLoan(address token) public view override returns (uint256) {\r
return token == address(this) ? _totalSupply : 0;\r
}\r
\r
function flashFee(address token, uint256 amount) public view override returns (uint256) {\r
require(token == address(this), "unsupported");\r
return (amount * fees.flashLoanFeeBasisPoints) / 10000;\r
}\r
\r
function flashLoan(\r
IERC3156FlashBorrower receiver,\r
address token,\r
uint256 amount,\r
bytes calldata data\r
) external override nonReentrant whenNotPaused returns (bool) {\r
require(token == address(this), "unsupported");\r
require(amount <= maxFlashLoan(token), "amount exceeds max");\r
require(!isBlackListed[address(receiver)], "receiver blacklisted");\r
require(!isBlackListed[msg.sender], "initiator blacklisted");\r
\r
uint256 fee = flashFee(token, amount);\r
uint256 balanceBefore = _balances[address(receiver)];\r
\r
// Transfer tokens to receiver\r
_balances[address(receiver)] += amount;\r
_totalSupply += amount; // Temporarily increase supply\r
\r
require(\r
receiver.onFlashLoan(msg.sender, token, amount, fee, data) == CALLBACK_SUCCESS,\r
"callback failed"\r
);\r
\r
// Ensure tokens + fee are returned\r
uint256 balanceAfter = _balances[address(receiver)];\r
require(balanceAfter >= balanceBefore + fee, "not repaid");\r
\r
// Remove the loaned amount and fee from receiver\r
_balances[address(receiver)] -= (amount + fee);\r
_totalSupply -= amount; // Restore original supply\r
\r
// Add fee to owner balance\r
if (fee > 0) {\r
_balances[state.owner] += fee;\r
}\r
\r
emit FlashLoan(msg.sender, address(receiver), amount, fee);\r
return true;\r
}\r
\r
function setFlashLoanFee(uint256 newFee) public onlyOwner {\r
require(newFee <= 100, "fee too high"); // Max 1%\r
fees.flashLoanFeeBasisPoints = newFee;\r
emit FlashLoanFeeUpdated(newFee);\r
}\r
}"
}
},
"settings": {
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-09-30 11:28:43
Comments
Log in to comment.
No comments yet.