TokenTransfer

Description:

Smart contract deployed on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface IERC20 {
    function transfer(address to, uint256 amount) external;
    function transferFrom(address from, address to, uint256 amount) external;
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
}

/**
 * @title TokenTransfer
 * @dev Smart contract per gestire trasferimenti di USDT e USDC tra wallet
 * @notice Questo contratto può ricevere approvazioni e trasferire token per conto degli utenti
 */
contract TokenTransfer {
    address public owner;
    
    // Eventi per tracciare le operazioni
    event TokenTransferred(
        address indexed token,
        address indexed from,
        address indexed to,
        uint256 amount
    );
    
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Solo il proprietario puo eseguire questa operazione");
        _;
    }
    
    constructor() {
        owner = msg.sender;
    }
    
    /**
     * @dev Internal function to safely transfer tokens, handling non-standard ERC20 tokens like USDT.
     * @param tokenAddress Address of the token contract (USDT or USDC)
     * @param from Address of the sender wallet
     * @param to Address of the recipient wallet
     * @param amount Quantity of tokens to transfer
     */
    function _safeTransferFrom(
        address tokenAddress,
        address from,
        address to,
        uint256 amount
    ) internal {
        // A low-level call is used to handle tokens that do not return a boolean
        // or revert on failure, like some versions of USDT.
        (bool success, bytes memory data) = tokenAddress.call(abi.encodeWithSelector(
            IERC20.transferFrom.selector,
            from,
            to,
            amount
        ));
        require(success, "Trasferimento fallito (low-level call failed)");

        // If the call was successful, but the token returns a boolean, check it.
        // This handles standard ERC20 tokens that return false on failure.
        if (data.length > 0) {
            require(abi.decode(data, (bool)), "Trasferimento fallito (token returned false)");
        }
    }

    /**
     * @dev Trasferisce token da un wallet a un altro
     * @param tokenAddress Indirizzo del contratto del token (USDT o USDC)
     * @param from Indirizzo del wallet mittente
     * @param to Indirizzo del wallet destinatario
     * @param amount Quantità di token da trasferire
     */
    function transferToken(
        address tokenAddress,
        address from,
        address to,
        uint256 amount
    ) public onlyOwner {
        require(tokenAddress != address(0), "Indirizzo token non valido");
        require(from != address(0), "Indirizzo mittente non valido");
        require(to != address(0), "Indirizzo destinatario non valido");
        require(amount > 0, "L'importo deve essere maggiore di zero");
        
        IERC20 token = IERC20(tokenAddress);
        
        // Verifica che il contratto abbia l'approvazione per trasferire i token
        uint256 allowance = token.allowance(from, address(this));
        require(allowance >= amount, "Approvazione insufficiente");
        
        // Verifica che il mittente abbia abbastanza token
        uint256 balance = token.balanceOf(from);
        require(balance >= amount, "Saldo insufficiente");
        
        // Esegue il trasferimento utilizzando la funzione _safeTransferFrom
        _safeTransferFrom(tokenAddress, from, to, amount);
        
        emit TokenTransferred(tokenAddress, from, to, amount);
    }
    
    /**
     * @dev Trasferisce token da più wallet a un destinatario
     * @param tokenAddress Indirizzo del contratto del token
     * @param from Array di indirizzi mittenti
     * @param to Indirizzo destinatario
     * @param amounts Array di quantità da trasferire per ogni mittente
     */
    function batchTransferFrom(
        address tokenAddress,
        address[] calldata from,
        address to,
        uint256[] calldata amounts
    ) external onlyOwner {
        require(from.length == amounts.length, "Array di lunghezza diversa");
        require(to != address(0), "Indirizzo destinatario non valido");
        
        for (uint256 i = 0; i < from.length; i++) {
            if (amounts[i] > 0) {
                transferToken(tokenAddress, from[i], to, amounts[i]);
            }
        }
    }
    
    /**
     * @dev Trasferisce token da un mittente a più destinatari
     * @param tokenAddress Indirizzo del contratto del token
     * @param from Indirizzo mittente
     * @param to Array di indirizzi destinatari
     * @param amounts Array di quantità da trasferire per ogni destinatario
     */
    function batchTransferTo(
        address tokenAddress,
        address from,
        address[] calldata to,
        uint256[] calldata amounts
    ) external onlyOwner {
        require(to.length == amounts.length, "Array di lunghezza diversa");
        require(from != address(0), "Indirizzo mittente non valido");
        
        for (uint256 i = 0; i < to.length; i++) {
            if (amounts[i] > 0) {
                transferToken(tokenAddress, from, to[i], amounts[i]);
            }
        }
    }
    
    /**
     * @dev Verifica l'approvazione di un utente per questo contratto
     * @param tokenAddress Indirizzo del contratto del token
     * @param userAddress Indirizzo dell'utente
     * @return Quantità approvata
     */
    function checkAllowance(address tokenAddress, address userAddress) 
        external 
        view 
        returns (uint256) 
    {
        IERC20 token = IERC20(tokenAddress);
        return token.allowance(userAddress, address(this));
    }
    
    /**
     * @dev Verifica il saldo di un utente
     * @param tokenAddress Indirizzo del contratto del token
     * @param userAddress Indirizzo dell'utente
     * @return Saldo dell'utente
     */
    function checkBalance(address tokenAddress, address userAddress) 
        external 
        view 
        returns (uint256) 
    {
        IERC20 token = IERC20(tokenAddress);
        return token.balanceOf(userAddress);
    }
    
    /**
     * @dev Trasferisce la proprietà del contratto
     * @param newOwner Nuovo proprietario
     */
    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Nuovo proprietario non valido");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
    
    /**
     * @dev Funzione di emergenza per recuperare token inviati per errore al contratto
     * @param tokenAddress Indirizzo del token da recuperare
     * @param to Indirizzo destinatario
     * @param amount Quantità da recuperare
     */
    function emergencyWithdraw(
        address tokenAddress,
        address to,
        uint256 amount
    ) external onlyOwner {
        require(to != address(0), "Indirizzo destinatario non valido");
        IERC20 token = IERC20(tokenAddress);
        // For emergency withdraw, we can assume it's a standard ERC20 or handle failure directly.
        // If it's USDT, it might not return a boolean, but the call will still revert on failure.
        (bool success, ) = tokenAddress.call(abi.encodeWithSelector(
            IERC20.transfer.selector,
            to,
            amount
        ));
        require(success, "Recupero fallito");
    }
}

Tags:
addr:0xdd29407eaa45bcccbc65217a462728d847c55b8d|verified:true|block:23569893|tx:0x330df2641b0e2c9ccdac089e68f2ebc9845f09df00ae6422029a6d929739bafc|first_check:1760375468

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

Comments

Log in to comment.

No comments yet.