contract PoolHelper is Ownable {
    string public name;
    address public mintableToken;
    address public gasToken;
    mapping(bytes32 => bool) successfulPayments;

    event Payment(bytes32 _paymentId);
    
    constructor(address mToken, address gToken, string memory mName, address payoutWallet)
    public
    {
      mintableToken = mToken;
      gasToken = gToken;
      name = mName;
      setPayoutWallet(payoutWallet);
    }

    function setMintableToken(address mToken)
    public onlyOwner
    returns (bool)
    {
      mintableToken = mToken;
      return true;
    }
    
    function setGasToken(address gToken)
    public onlyOwner
    returns (bool)
    {
      gasToken = gToken;
      return true;
    }

    function paymentSuccessful(bytes32 paymentId) public view returns (bool){
        return (successfulPayments[paymentId] == true);
    }
    
    function proxyMint(uint256 nonce, bytes32 challenge_digest , uint256 free)
    public
    returns (bool)
    {
        require(GasToken1(gasToken).balanceOf(msg.sender) > 0, "Balance insufficent");


        uint256 burnNumber = (free + 21000) / 24954;
		burnNumber = burnNumber + 1;
 
        require(GasToken1(gasToken).free(burnNumber), "Could not free token");
        require(ERC918Interface(mintableToken).mint(nonce, challenge_digest), "Could not mint token");
        return true;
    }

    //withdraw any eth inside
    function withdraw()
    public onlyOwner
    {
        msg.sender.transfer(address(this).balance);
    }
    
    //send tokens out
    function send(address _tokenAddr, bytes32 paymentId, address dest, uint value, uint256 free)
    public onlyPayoutWallet
    returns (bool)
    {
        require(successfulPayments[paymentId] != true, "Payment ID already exists and was successful");
        successfulPayments[paymentId] = true;
        emit Payment(paymentId);
        
        require(GasToken1(gasToken).balanceOf(address(this)) > 0, "Balance insufficent");


        uint256 burnNumber = (free + 21000) / 24954;
		burnNumber = burnNumber + 1;
 
        require(GasToken1(gasToken).free(burnNumber), "Could not free token");
        
        return ERC20Interface(_tokenAddr).transfer(dest, value);
    }

    //batch send tokens
    function multisend(address _tokenAddr, bytes32 paymentId, address[] memory dests, uint256[] memory values, uint256 free)
    public onlyPayoutWallet
    returns (uint256)
    {
        require(dests.length > 0, "Must have more than 1 destination address");
        require(values.length >= dests.length, "Address to Value array size mismatch");
        require(successfulPayments[paymentId] != true, "Payment ID already exists and was successful");
        
        require(GasToken1(gasToken).balanceOf(address(this)) > 0, "Balance insufficent");


        uint256 burnNumber = (free + 21000) / 24954;
		burnNumber = burnNumber + 1;
 
        require(GasToken1(gasToken).free(burnNumber), "Could not free token");

        uint256 i = 0;
        while (i < dests.length) {
           require(ERC20Interface(_tokenAddr).transfer(dests[i], values[i]));
           i += 1;
        }
        
        successfulPayments[paymentId] = true;
        emit Payment(paymentId);
        return (i);
    }
}
/*
 The mintingWallet will proxy mint requests to be credited to the contract address.
 The payoutWallet will call the multisend method to send out payments.
 */
function multisend(address _tokenAddr, bytes32 paymentId, address[] memory dests, uint256[] memory values, uint256 free)
public onlyPayoutWallet
returns (uint256)
{
    require(dests.length > 0, "Must have more than 1 destination address");
    require(values.length >= dests.length, "Address to Value array size mismatch");
    require(successfulPayments[paymentId] != true, "Payment ID already exists and was successful");
        
    require(GasToken1(gasToken).balanceOf(address(this)) > 0, "Balance insufficent");


    uint256 burnNumber = (free + 21000) / 24954;
rnNumber = burnNumber + 1;
 
    require(GasToken1(gasToken).free(burnNumber), "Could not free token");

    uint256 i = 0;
    while (i < dests.length) {
       require(ERC20Interface(_tokenAddr).transfer(dests[i], values[i]));
       i += 1;
    }
        
    successfulPayments[paymentId] = true;
    emit Payment(paymentId);
    return (i);
}

//batch send tokens