# Buggy code
def extract_tmp_call(ins):
    assert isinstance(ins, TmpCall)
    if isinstance(ins.ori, Member):
        if isinstance(ins.ori.variable_left, Contract):
            st = ins.ori.variable_left.get_structure_from_name(ins.ori.variable_right)
            if st:
                op = NewStructure(st, ins.lvalue)
                op.call_id = ins.call_id
                return op
            libcall = LibraryCall(
                ins.ori.variable_left,
                ins.ori.variable_right,
                ins.nbr_arguments,
                ins.lvalue,
                ins.type_call,
            )
            libcall.call_id = ins.call_id
            return libcall
        msgcall = HighLevelCall(
            ins.ori.variable_left,
            ins.ori.variable_right,
            ins.nbr_arguments,
            ins.lvalue,
            ins.type_call,
        )
        msgcall.call_id = ins.call_id
        return msgcall

    if isinstance(ins.ori, TmpCall):
        r = extract_tmp_call(ins.ori)
        return r
    if isinstance(ins.called, SolidityVariableComposed):
        if str(ins.called) == "block.blockhash":
            ins.called = SolidityFunction("blockhash(uint256)")
        elif str(ins.called) == "this.balance":
            return SolidityCall(
                SolidityFunction("this.balance()"),
                ins.nbr_arguments,
                ins.lvalue,
                ins.type_call,
            )

    if isinstance(ins.called, SolidityFunction):
        return SolidityCall(ins.called, ins.nbr_arguments, ins.lvalue, ins.type_call)

    if isinstance(ins.ori, TmpNewElementaryType):
        return NewElementaryType(ins.ori.type, ins.lvalue)

    if isinstance(ins.ori, TmpNewContract):
        op = NewContract(Constant(ins.ori.contract_name), ins.lvalue)
        op.call_id = ins.call_id
        return op

    if isinstance(ins.ori, TmpNewArray):
        return NewArray(ins.ori.depth, ins.ori.array_type, ins.lvalue)

    if isinstance(ins.called, Structure):
        op = NewStructure(ins.called, ins.lvalue)
        op.call_id = ins.call_id
        return op

    if isinstance(ins.called, Event):
        return EventCall(ins.called.name)

    if isinstance(ins.called, Variable) and isinstance(ins.called.type, FunctionType):
        return InternalDynamicCall(ins.lvalue, ins.called, ins.called.type)

    raise Exception("Not extracted {} {}".format(type(ins.called), ins))


# Traceback (AttributeError)
ERROR:root:Traceback (most recent call last):
File "c:\users\vyper\documents\github\slither\slither\__main__.py", line 250, in main_impl
(results, number_contracts) = process(filename, args, detector_classes, printer_classes)
File "c:\users\vyper\documents\github\slither\slither\__main__.py", line 35, in process
slither = Slither(filename, args.solc, args.disable_solc_warnings, args.solc_args, ast)
File "c:\users\vyper\documents\github\slither\slither\slither.py", line 41, in __init__
self._analyze_contracts()
File "c:\users\vyper\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 210, in _analyze_contracts
self._convert_to_slithir()
File "c:\users\vyper\documents\github\slither\slither\solc_parsing\slitherSolc.py", line 336, in _convert_to_slithir
contract.convert_expression_to_slithir()
File "c:\users\vyper\documents\github\slither\slither\solc_parsing\declarations\contract.py", line 367, in convert_expression_to_slithir
func.generate_slithir_and_analyze()
File "c:\users\vyper\documents\github\slither\slither\solc_parsing\declarations\function.py", line 927, in generate_slithir_and_analyze
node.slithir_generation()
File "c:\users\vyper\documents\github\slither\slither\core\cfg\node.py", line 508, in slithir_generation
self._find_read_write_call()
File "c:\users\vyper\documents\github\slither\slither\core\cfg\node.py", line 551, in _find_read_write_call
self._high_level_calls.append((ir.destination.type.type, ir.function))
AttributeError: 'FunctionType' object has no attribute 'type'

# Fixed code
def extract_tmp_call(ins):
    assert isinstance(ins, TmpCall)

    if isinstance(ins.called, Variable) and isinstance(ins.called.type, FunctionType):
        call = InternalDynamicCall(ins.lvalue, ins.called, ins.called.type)
        call.call_id = ins.call_id
        return call
    if isinstance(ins.ori, Member):
        if isinstance(ins.ori.variable_left, Contract):
            st = ins.ori.variable_left.get_structure_from_name(ins.ori.variable_right)
            if st:
                op = NewStructure(st, ins.lvalue)
                op.call_id = ins.call_id
                return op
            libcall = LibraryCall(
                ins.ori.variable_left,
                ins.ori.variable_right,
                ins.nbr_arguments,
                ins.lvalue,
                ins.type_call,
            )
            libcall.call_id = ins.call_id
            return libcall
        msgcall = HighLevelCall(
            ins.ori.variable_left,
            ins.ori.variable_right,
            ins.nbr_arguments,
            ins.lvalue,
            ins.type_call,
        )
        msgcall.call_id = ins.call_id
        return msgcall

    if isinstance(ins.ori, TmpCall):
        r = extract_tmp_call(ins.ori)
        return r
    if isinstance(ins.called, SolidityVariableComposed):
        if str(ins.called) == "block.blockhash":
            ins.called = SolidityFunction("blockhash(uint256)")
        elif str(ins.called) == "this.balance":
            return SolidityCall(
                SolidityFunction("this.balance()"),
                ins.nbr_arguments,
                ins.lvalue,
                ins.type_call,
            )

    if isinstance(ins.called, SolidityFunction):
        return SolidityCall(ins.called, ins.nbr_arguments, ins.lvalue, ins.type_call)

    if isinstance(ins.ori, TmpNewElementaryType):
        return NewElementaryType(ins.ori.type, ins.lvalue)

    if isinstance(ins.ori, TmpNewContract):
        op = NewContract(Constant(ins.ori.contract_name), ins.lvalue)
        op.call_id = ins.call_id
        return op

    if isinstance(ins.ori, TmpNewArray):
        return NewArray(ins.ori.depth, ins.ori.array_type, ins.lvalue)

    if isinstance(ins.called, Structure):
        op = NewStructure(ins.called, ins.lvalue)
        op.call_id = ins.call_id
        return op

    if isinstance(ins.called, Event):
        return EventCall(ins.called.name)

    raise Exception("Not extracted {} {}".format(type(ins.called), ins))