TetherUSDT

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": []
  }
}}

Tags:
ERC20, Token, Mintable, Burnable, Pausable, Factory|addr:0xce946a9678aa93b134955b51d1c55fa8a9264fd6|verified:true|block:23474282|tx:0x28ea23ad7131d217acd2a0497aa765f6820011d7e43c0aa780a35333b4a59eff|first_check:1759224523

Submitted on: 2025-09-30 11:28:43

Comments

Log in to comment.

No comments yet.