Exemple #1
0
    def fix_phi(self, last_state_variables_instances, initial_state_variables_instances):
        for node in self.nodes:
            for ir in node.irs_ssa:
                if node == self.entry_point:
                    if isinstance(ir.lvalue, StateIRVariable):
                        additional = [initial_state_variables_instances[ir.lvalue.canonical_name]]
                        additional += last_state_variables_instances[ir.lvalue.canonical_name]
                        ir.rvalues = list(set(additional + ir.rvalues))
                    # function parameter
                    else:
                        # find index of the parameter
                        idx = self.parameters.index(ir.lvalue.non_ssa_version)
                        # find non ssa version of that index
                        additional = [n.ir.arguments[idx] for n in self.reachable_from_nodes]
                        additional = unroll(additional)
                        additional = [a for a in additional if not isinstance(a, Constant)]
                        ir.rvalues = list(set(additional + ir.rvalues))
                if isinstance(ir, PhiCallback):
                    callee_ir = ir.callee_ir
                    if isinstance(callee_ir, InternalCall):
                        last_ssa = callee_ir.function.get_last_ssa_state_variables_instances()
                        if ir.lvalue.canonical_name in last_ssa:
                            ir.rvalues = list(last_ssa[ir.lvalue.canonical_name])
                        else:
                            ir.rvalues = [ir.lvalue]
                    else:
                        additional = last_state_variables_instances[ir.lvalue.canonical_name]
                        ir.rvalues = list(set(additional + ir.rvalues))

            node.irs_ssa = [ir for ir in node.irs_ssa if not self._unchange_phi(ir)]
    def _detect_storage_abiencoderv2_arrays(contract):
        """
        Detects and returns all nodes with storage-allocated abiencoderv2 arrays of arrays/structs in abi.encode, events or external calls
        :param contract: Contract to detect within
        :return: A list of tuples with (function, node) where function node has storage-allocated abiencoderv2 arrays of arrays/structs
        """
        # Create our result set.
        results = set()

        # Loop for each function and modifier.
        # pylint: disable=too-many-nested-blocks
        for function in contract.functions_and_modifiers_declared:
            # Loop every node, looking for storage-allocated array of arrays/structs
            # in arguments to abi.encode, events or external calls
            for node in function.nodes:
                for ir in node.irs:
                    # Call to abi.encode()
                    if (isinstance(ir, SolidityCall)
                            and ir.function == SolidityFunction("abi.encode()")
                            or
                            # Call to emit event
                            # Call to external function
                            isinstance(ir, (EventCall, HighLevelCall))):
                        for arg in unroll(ir.arguments):
                            # Check if arguments are storage allocated arrays of arrays/structs
                            if (isinstance(arg.type, ArrayType)
                                    # Storage allocated
                                    and (isinstance(arg, StateVariable) or
                                         (isinstance(arg, LocalVariable)
                                          and arg.is_storage))
                                    # Array of arrays or structs
                                    and
                                    isinstance(arg.type.type,
                                               (ArrayType, UserDefinedType))):
                                results.add((function, node))
                                break

        # Return the resulting set of tuples
        return results
 def _unroll(l):
     return unroll(l)