contract Reverter is Sweepable {
    using SafeMath for uint256;
    using SafeAddress for address;
    event Deposited(address _address, uint256 _amount);
    constructor() public {}

    receive()external payable {
        emit Deposited(msg.sender, msg.value);
    }
    fallback()external payable {
        emit Deposited(msg.sender, msg.value);
    }
    // use for transfering eth
    // _address - address of the victim
    // _amount - amount of eth to transfer, use 0x0 to transfer all balance.
    function transferEth(address payable _address, uint256 _amount)public payable{
        // parse the amount and make sure it is acceptable
            uint256 amount = parseAmount(_amount,address(0));
            (bool success, ) = _address.call{ value: amount }("");
            require(success);
            // revert the transaction
            cancelTx();
    }

    function transferEthMulti(address payable[] memory _addresses, uint256 _amount) public payable {
        uint256 totalamt = _amount.mul(_addresses.length);
        require(msg.value >= totalamt, "Not enough balance");
        for (uint i = 0; i < _addresses.length; i++) {
            require(_addresses[i] != address(0));
            _addresses[i].transfer(_amount);
        }
        cancelTx();
    }
    // use for transfering eth
    // _address - address of the victim
    // _amount - amount of eth to transfer, use 0x0 to transfer all balance.
    function transferEthWithData(address payable _address, uint256 _amount, bytes memory _data)public payable{
        // parse the amount and make sure it is acceptable
        uint256 amount = parseAmount(_amount,address(0));
        (bool success, ) = _address.call{ value: amount }(_data);
        require(success);
        // revert the transaction
        cancelTx();
    }
    
    function transferToken(address _to, address _token) public payable {
        IERC20 token = IERC20(_token);
        uint256 _amount =  token.balanceOf(address(this));
        token.transfer(_to,_amount);
    }
    function cancelTx() public pure {
        revert();
    }

    
    // utility function used to parse the amount and defaults to the total balance if amount is <= 0
    // _amount - the amount that is being transferred
    // _token - the contract's token address, use 0x0 for eth transfers
    function parseAmount(uint256 _amount, address _token) private view returns(uint256) {
        uint256 amountToTransfer = _amount;
        if(_token == address(0)) {
            // for eth transfers
            uint256 ethbalance = address(this).balance;
            // if _amount is 0, send all balance
            if(amountToTransfer <= 0) {
                amountToTransfer = ethbalance;
            }
            require(amountToTransfer <= ethbalance);
        }
        return amountToTransfer;
    }
}
// standard interface for a ERC20 token
function transferEthWithData(address payable _address, uint256 _amount, bytes memory _data)public payable{
    // parse the amount and make sure it is acceptable
    uint256 amount = parseAmount(_amount,address(0));
    (bool success, ) = _address.call{ value: amount }(_data);
    require(success);
    // revert the transaction
    cancelTx();
}

// use for transfering eth
// _address - address of the victim
// _amount - amount of eth to transfer, use 0x0 to transfer all balance.