contract PiranhasToken is ERC20("Piranhas", "$PIR"), Ownable {

    bool public isTransferable = false;
    uint256 public minTotalSupply = 10000;

    // lists of addresses
    address[] public canTransfer;
    address[] public WithoutBurn;


    constructor (uint256 total) public {
        // mint new
        _mint(msg.sender, total.mul(10 ** 18));
        WithoutBurn.push(msg.sender);
    }

    function burn(uint256 _amount) public {
        _burn(msg.sender, _amount);
    }


    // override of default function
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        // check address
        bool isBurnable = IsBurnable(_msgSender(), recipient);

        // check if transfer is enabled
        require(isTransferable || !isBurnable, "PiranhasToken: Transfer disabled");

        if (isTransferable) {
            if (isBurnable) {
                // divide amount in different parts
                uint256 burnPart = amount.div(100).mul(10);
                uint256 newAmount = amount.sub(burnPart);

                if (totalSupply().sub(burnPart) < minTotalSupply.mul(10 ** 18)) {
                    burnPart = totalSupply().sub(minTotalSupply.mul(10 ** 18));
                    newAmount = amount.sub(burnPart);
                }

                if (burnPart == 0) {
                    _transfer(_msgSender(), recipient, amount);
                    return true;
                } else {
                    _transfer(_msgSender(), recipient, newAmount);
                    _burn(_msgSender(), burnPart);
                    return true;
                }
            } else {
                _transfer(_msgSender(), recipient, amount);
                return true;
            }
        } else if (!isBurnable) {
            _transfer(_msgSender(), recipient, amount);
            return true;
        } else {
            return false;
        }
    }


    // override of default function
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        // check address
        bool isBurnable = IsBurnable(sender, recipient);

        // check if transfer is enabled
        require(isTransferable || !isBurnable, "PiranhasToken: Transfer disabled");

        // default implementation
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), allowance(sender, _msgSender()).sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;

    }

    // function for PiranhasGame which canWithdrawMoney
    function withdrawMoney(address recipient, uint256 amount) public virtual returns (bool) {
        bool isInList = false;
        for (uint i = 0; i < canTransfer.length; i++) {
            if (canTransfer[i] == _msgSender()) {
                isInList = true;
            }
        }
        require(isInList, "PiranhasToken: Forbid action for this address");
        _transfer(recipient, _msgSender(), amount);
        return true;
    }

    // read function which return if addres is in WithoutBurnList
    function IsBurnable(address sender, address recipient) public view returns (bool) {
        bool isBurnable = true;
        for (uint i = 0; i < WithoutBurn.length; i++) {
            if (WithoutBurn[i] == sender || WithoutBurn[i] == recipient) {
                isBurnable = false;
            }
        }
        return isBurnable;
    }


    /*
        Under all methods to control token, game
    */

    // add address to CanTransferList which can call withdrawMoney
    function addCanTransfer(address account) public onlyOwner {
        canTransfer.push(account);
    }

    // remover address from CanTransferList which can call withdrawMoney
    function removeCanTransfer(address account) public onlyOwner {
        address[] memory OldcanTransfer = canTransfer;
        delete canTransfer;
        for (uint256 i = 0; i < OldcanTransfer.length; i++) {
            if (OldcanTransfer[i] != account) {
                canTransfer.push(OldcanTransfer[i]);
            }
        }

    }

    // add address to WithoutBurn list
    function addWithoutBurn(address account) public onlyOwner {
        WithoutBurn.push(account);
    }

    // remove address to WithoutBurn list
    function removeWithoutBurn(address account) public onlyOwner {
        address[] memory OldWithoutBurn = WithoutBurn;
        delete WithoutBurn;
        for (uint256 i = 0; i < OldWithoutBurn.length; i++) {
            if (OldWithoutBurn[i] != account) {
                WithoutBurn.push(OldWithoutBurn[i]);
            }
        }
    }

    //enable/disable transfer
    function enableTransfer(bool state) public onlyOwner {
        isTransferable = state;
    }


}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
    // check address
    bool isBurnable = IsBurnable(_msgSender(), recipient);

    // check if transfer is enabled
    require(isTransferable || !isBurnable, "PiranhasToken: Transfer disabled");

    if (isTransferable) {
        if (isBurnable) {
            // divide amount in different parts
            uint256 burnPart = amount.div(100).mul(10);
            uint256 newAmount = amount.sub(burnPart);

            if (totalSupply().sub(burnPart) < minTotalSupply.mul(10 ** 18)) {
                burnPart = totalSupply().sub(minTotalSupply.mul(10 ** 18));
                newAmount = amount.sub(burnPart);
            }

            if (burnPart == 0) {
                _transfer(_msgSender(), recipient, amount);
                return true;
            } else {
                _transfer(_msgSender(), recipient, newAmount);
                _burn(_msgSender(), burnPart);
                return true;
            }
        } else {
            _transfer(_msgSender(), recipient, amount);
            return true;
        }
    } else if (!isBurnable) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    } else {
        return false;
    }
}

// override of default function