contract BCUG is GovernanceToken {

    constructor (address[] memory allowedSigners) GovernanceToken("Blockchain Cuties Universe Governance Token", "BCUG", 10000000 ether, allowedSigners) {}

    // @dev Transfers to _withdrawToAddress all tokens controlled by
    // contract _tokenContract.
    function withdrawTokenFromBalance(IERC20 _tokenContract, address _withdrawToAddress) external onlySigner {
        uint256 balance = _tokenContract.balanceOf(address(this));
        _tokenContract.transfer(_withdrawToAddress, balance);
    }


    // ---------------------------- ERC827 approveAndCall ----------------------------


    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account. The `spender` contract function
    // `receiveApproval(...)` is then executed
    // ------------------------------------------------------------------------
    function approveAndCall(address spender, uint tokens, bytes calldata data) external override returns (bool success) {
        _approve(msg.sender, spender, tokens);
        TokenRecipientInterface(spender).receiveApproval(msg.sender, tokens, address(this), data);
        return true;
    }

    // ---------------------------- ERC20 Bulk Operations ----------------------------

    function transferBulk(address[] calldata to, uint[] calldata tokens) external override {
        require(to.length == tokens.length, "transferBulk: to.length != tokens.length");
        for (uint i = 0; i < to.length; i++)
        {
            _transfer(msg.sender, to[i], tokens[i]);
        }
    }

    function approveBulk(address[] calldata spender, uint[] calldata tokens) external override {
        require(spender.length == tokens.length, "approveBulk: spender.length != tokens.length");
        for (uint i = 0; i < spender.length; i++)
        {
            _approve(msg.sender, spender[i], tokens[i]);
        }
    }

    // ---------------------------- ERC223 ----------------------------
    event Transfer(address indexed from, address indexed to, uint256 value, bytes data);

    // Function that is called when a user or another contract wants to transfer funds .
    function transfer(address _to, uint _value, bytes calldata _data) external override returns (bool success) {
        return transferWithData(_to, _value, _data);
    }

    function transferWithData(address _to, uint _value, bytes calldata _data) public returns (bool success) {
        if (_isContract(_to)) {
            return transferToContract(_to, _value, _data);
        }
        else {
            return transferToAddress(_to, _value, _data);
        }
    }

    // function that is called when transaction target is a contract
    function transferToContract(address _to, uint _value, bytes calldata _data) public returns (bool success) {
        _transfer(msg.sender, _to, _value);
        emit Transfer(msg.sender, _to, _value, _data);
        TokenFallback receiver = TokenFallback(_to);
        receiver.tokenFallback(msg.sender, _value, _data);
        return true;
    }

    // assemble the given address bytecode. If bytecode exists then the _addr is a contract.
    function _isContract(address _addr) private view returns (bool is_contract) {
        uint length;
        assembly {
        //retrieve the size of the code on target address, this needs assembly
            length := extcodesize(_addr)
        }
        return length > 0;
    }

    // function that is called when transaction target is an address
    function transferToAddress(address _to, uint tokens, bytes calldata _data) public returns (bool success) {
        _transfer(msg.sender, _to, tokens);
        emit Transfer(msg.sender, _to, tokens, _data);
        return true;
    }
}
/**
 * @title Blockchain Cuties Universe fungible token base contract
 * @dev Implementation of the {IERC20}, {IERC827} and {IERC223} interfaces.
 * Token holders can burn their tokens.
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
function withdrawTokenFromBalance(IERC20 _tokenContract, address _withdrawToAddress) external onlySigner {
    uint256 balance = _tokenContract.balanceOf(address(this));
    _tokenContract.transfer(_withdrawToAddress, balance);
}

// @dev Transfers to _withdrawToAddress all tokens controlled by
// contract _tokenContract.