contract TatauToken is MiniMeToken {
    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed burner, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 amount, bytes data);

    constructor(address _tokenFactory, address _foreignBridge) public MiniMeToken(
        _tokenFactory,
        0x0,
        0,
        "Tatau Token",
        18,
        "TATAU",
        true
    ) {
        foreignBridge = _foreignBridge;
    }

    address public foreignBridge;

    modifier onlyForeignBridge {
        require(msg.sender == foreignBridge);
        _;
    }

    /// @notice Send `_amount` tokens to `_to` from `msg.sender` and call
    /// `contractFallback` on the recipient if it is a Contract.
    /// @param _to The address of the recipient
    /// @param _amount The amount of tokens to be transferred
    /// @param _data Additional bytes that will be passed to `contractFallback`
    /// @return Whether the transfer was successful or not
    function transferAndCall(address _to, uint256 _amount, bytes _data)
        external returns (bool)
    {
        require(transfer(_to, _amount));
        emit Transfer(msg.sender, _to, _amount, _data);
        if (isContract(_to)) {
            require(contractFallback(_to, _amount, _data));
        }
        return true;
    }

    /// @notice Changes the foreignBridge
    /// @param _newForeignBridge The foreign bridge address
    function changeForeignBridge(address _newForeignBridge)
        public onlyController
    {
        foreignBridge = _newForeignBridge;
    }

    /// @notice Mints `_amount` tokens that are assigned to `_owner`
    /// @param _amount The quantity of tokens to mint
    /// @return True if the tokens are generated correctly
    function mint(address _to, uint _amount)
        public onlyForeignBridge returns (bool)
    {
        uint curTotalSupply = totalSupply();
        require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow
        uint previousBalanceTo = balanceOf(_to);
        require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow
        updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount);
        updateValueAtNow(balances[_to], previousBalanceTo + _amount);
        emit Mint(_to, _amount);
        emit Transfer(0x0, _to, _amount);
        return true;
    }

    /// @notice Burns `_amount` tokens from `_owner`
    /// @param _amount The quantity of tokens to burn
    /// @return True if the tokens are burned correctly
    function burn(uint _amount)
        public onlyForeignBridge returns (bool)
    {
        uint curTotalSupply = totalSupply();
        require(curTotalSupply >= _amount);
        uint previousBalanceFrom = balanceOf(msg.sender);
        require(previousBalanceFrom >= _amount);
        updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount);
        updateValueAtNow(balances[msg.sender], previousBalanceFrom - _amount);
        emit Burn(msg.sender, _amount);
        emit Transfer(msg.sender, 0x0, _amount);
        return true;
    }

    function contractFallback(address _to, uint _value, bytes _data)
        private returns(bool)
    {
        ERC677Receiver receiver = ERC677Receiver(_to);
        return receiver.onTokenTransfer(msg.sender, _value, _data);
    }
}
function burn(uint _amount)
    public onlyForeignBridge returns (bool)
{
    uint curTotalSupply = totalSupply();
    require(curTotalSupply >= _amount);
    uint previousBalanceFrom = balanceOf(msg.sender);
    require(previousBalanceFrom >= _amount);
    updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount);
    updateValueAtNow(balances[msg.sender], previousBalanceFrom - _amount);
    emit Burn(msg.sender, _amount);
    emit Transfer(msg.sender, 0x0, _amount);
    return true;
}

/// @notice Burns `_amount` tokens from `_owner`
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly