diff --git a/config.yml b/config.yml index bd22b97..606355c 100644 --- a/config.yml +++ b/config.yml @@ -1,11 +1,11 @@ compilers: - - name: venom + - name: adder queue: host: localhost port: 5672 exec_params: - venom: True - - name: default + venom: False + - name: nagini queue: host: localhost port: 5673 diff --git a/converters/typed_converters.py b/converters/typed_converters.py index 5b8526a..5e14712 100644 --- a/converters/typed_converters.py +++ b/converters/typed_converters.py @@ -134,6 +134,7 @@ def visit(self): """ Runs the conversion of the message and stores the result in the result variable """ + random.seed(0) for i, var in enumerate(self.contract.decls): if i >= MAX_STORAGE_VARIABLES: break @@ -531,36 +532,36 @@ def _visit_assignment(self, assignment): def _visit_statement(self, statement): # if not in `for` theres always assignment; probs need another default value if self._for_block_count > 0: - if statement.HasField("cont_stmt"): + if _has_field(statement, "cont_stmt"): return self._visit_continue_statement() - if statement.HasField("break_stmt"): + if _has_field(statement, "break_stmt"): return self._visit_break_statement() - if statement.HasField("decl"): + if _has_field(statement, "decl"): return self.visit_var_decl(statement.decl) - if statement.HasField("for_stmt"): + if _has_field(statement, "for_stmt"): return self._visit_for_stmt(statement.for_stmt) - if statement.HasField("if_stmt"): + if _has_field(statement, "if_stmt"): return self._visit_if_stmt(statement.if_stmt) - if statement.HasField("assert_stmt"): + if _has_field(statement, "assert_stmt"): return self._visit_assert_stmt(statement.assert_stmt) - if statement.HasField("func_call"): + if _has_field(statement, "func_call"): if len(self._func_tracker) > 0: func_num = statement.func_call.func_num % len(self._func_tracker) if func_num in self._function_call_map[self._current_func.id]: return self._visit_func_call(statement.func_call) - if statement.HasField("append_stmt"): + if _has_field(statement, "append_stmt"): append_st = self._visit_append_stmt(statement.append_stmt) if append_st is not None: return append_st - if statement.HasField("pop_stmt"): + if _has_field(statement, "pop_stmt"): pop_st = self._visit_pop_stmt(statement.pop_stmt) if pop_st is not None: return pop_st - if statement.HasField("send_stmt"): + if _has_field(statement, "send_stmt"): return self._visit_send_stmt(statement.send_stmt) - if statement.HasField("raw_call"): + if _has_field(statement, "raw_call"): return self._visit_raw_call(statement.raw_call) - if statement.HasField("raw_log"): + if _has_field(statement, "raw_log"): return self._visit_raw_log(statement.raw_log) return self._visit_assignment(statement.assignment) @@ -687,17 +688,17 @@ def visit_address_expression(self, expr): # result = self._visit_convert(expr.convert) # return result current_type = self.type_stack[-1] - if expr.HasField("cmp") and not self._is_constant: + if _has_field(expr, "cmp") and not self._is_constant: name = "create_minimal_proxy_to" return self.visit_create_min_proxy_or_copy_of(expr.cmp, name) - if expr.HasField("cfb") and not self._is_constant: + if _has_field(expr, "cfb") and not self._is_constant: return self.visit_create_from_blueprint(expr.cfb) - if expr.HasField("cco") and not self._is_constant: + if _has_field(expr, "cco") and not self._is_constant: name = "create_copy_of" return self.visit_create_min_proxy_or_copy_of(expr.cco, name) - if expr.HasField("ecRec"): + if _has_field(expr, "ecRec"): return self.visit_ecrecover(expr.ecRec) - if expr.HasField("varRef"): + if _has_field(expr, "varRef"): # TODO: it has to be decided how exactly to track a current block level or if it has to be passed result = self._visit_var_ref(expr.varRef, self._block_level_count) if result is not None: diff --git a/converters/typed_converters_4.py b/converters/typed_converters_4.py index 1f8e6b7..b6de437 100644 --- a/converters/typed_converters_4.py +++ b/converters/typed_converters_4.py @@ -51,7 +51,7 @@ def visit_init(self, init): # https://github.com/vyperlang/vyper/pull/3769 def _visit_reentrancy(self, ret): - return "@nonreentrant" + return "@nonreentrant\n" # https://github.com/vyperlang/vyper/pull/2937 def _visit_int_expression(self, expr): diff --git a/proto_loader.py b/proto_loader.py index 28fe68c..8de9eaa 100644 --- a/proto_loader.py +++ b/proto_loader.py @@ -2,6 +2,9 @@ import vyper conf = Config() + +from vyperProtoNewRawCallBug_pb2 import * +""" if vyper.__version__ == '0.3.10': from vyperProtoNew_pb2 import * # 0.3.10 and 0.4.0 w decimals are the same for now @@ -10,3 +13,4 @@ from vyperProtoNew_pb2 import * elif vyper.__version__ == '0.4.0': from vyperProtoNewNoDecimal_pb2 import * +""" \ No newline at end of file diff --git a/run.py b/run.py index e0f1883..e9054eb 100644 --- a/run.py +++ b/run.py @@ -16,7 +16,7 @@ with atheris.instrument_imports(): import sys import vyper - #from converters.typed_converters import TypedConverter + from converters.typed_converters import TypedConverter from converters.typed_converters_4 import NaginiConverter __version__ = "0.1.3" # same version as images' one @@ -45,7 +45,8 @@ def TestOneProtoInput(msg): data = { "json_msg": MessageToJson(msg), - "generation_result": None, + "generation_result_nagini": None, + "generation_result_adder": None, "compilation_result": None, "error_type": None, "error_message": None, @@ -57,8 +58,10 @@ def TestOneProtoInput(msg): c_log = db_client["compilation_log"] f_log = db_client['failure_log'] try: - proto = NaginiConverter(msg) - proto.visit() + proto_converter_nagini = NaginiConverter(msg) + proto_converter_nagini.visit() + proto_converter_adder = TypedConverter(msg) + proto_converter_adder.visit() except Exception as e: converter_error = { "error_type": type(e).__name__, @@ -69,9 +72,10 @@ def TestOneProtoInput(msg): logger.critical("Converter has crashed: %s", converter_error) raise e # Do we actually want to fail here? - data["generation_result"] = proto.result + data["generation_result_nagini"] = proto_converter_nagini.result + data["generation_result_adder"] = proto_converter_adder.result try: - c_result = vyper.compile_code(proto.result) + c_result = vyper.compile_code(proto_converter_nagini.result) data["compilation_result"] = c_result except Exception as e: data["error_type"] = type(e).__name__ @@ -80,7 +84,7 @@ def TestOneProtoInput(msg): logger.debug("Compilation result: %s", data) input_values = dict() - for name, types in proto.function_inputs.items(): + for name, types in proto_converter_nagini.function_inputs.items(): for i in conf.input_strategies: input_generator.change_strategy(InputStrategy(i)) @@ -96,7 +100,8 @@ def TestOneProtoInput(msg): message = { "_id": str(ins_res.inserted_id), - "generation_result": proto.result, + "generation_result_nagini": proto_converter_nagini.result, + "generation_result_adder": proto_converter_adder.result, "function_input_values": input_values, "json_msg": MessageToJson(msg), "generator_version": __version__, diff --git a/tests/integration_runner/runner.py b/tests/integration_runner/runner.py index ab91c0e..3546ff4 100644 --- a/tests/integration_runner/runner.py +++ b/tests/integration_runner/runner.py @@ -19,7 +19,8 @@ conf = Config("./config.yml") compiler_params = conf.get_compiler_params_by_name(compiler_name) -compiler_key = f"{vyper.__version__.replace('.', '_')}_{compiler_name}" +#compiler_key = f"{vyper.__version__.replace('.', '_')}_{compiler_name}" +compiler_key = f"{compiler_name}" logger_level = getattr(logging, conf.verbosity) logger = logging.getLogger(f"runner_{compiler_key}") @@ -74,7 +75,7 @@ def handle_compilation(_contract_desc): for iv in init_values: logger.debug("Constructor values: %s", iv) try: - contract = boa.loads(_contract_desc["generation_result"], + contract = boa.loads(_contract_desc[f"generation_result_{compiler_key}"], *iv, compiler_args=comp_settings) except Exception as e: logger.debug("Deployment failed: %s", str(e)) diff --git a/verifiers/simple_verifier.py b/verifiers/simple_verifier.py index 94f3a8c..0a73bce 100644 --- a/verifiers/simple_verifier.py +++ b/verifiers/simple_verifier.py @@ -35,9 +35,23 @@ def runtime_error_handler(_res0, _res1): pass +def compilation_error_handler(_res0, _res1): + if _res0 != _res1: + raise VerifierException(f"Compilation error discrepancy: {_res0} | {_res1}") + RUNTIME_ERROR = "runtime_error" +def verify_and_catch(verifier, params): + try: + verifier(*params) + err = None + except VerifierException as e: + logger.error(str(e)) + err = str(e) + return err + + def verify_two_results(_res0, _res1): if RUNTIME_ERROR in _res0 or RUNTIME_ERROR in _res1: runtime_error_handler(_res0, _res1) @@ -50,12 +64,7 @@ def verify_two_results(_res0, _res1): } d = {} for name, (verifier, params) in verifiers.items(): - try: - verifier(*params) - d[name] = None - except VerifierException as e: - logger.error(str(e)) - d[name] = str(e) + d[name] = verify_and_catch(verifier, params) return d @@ -80,7 +89,7 @@ def verify_results(_conf: Config, data): def target_fields(_conf: Config) -> list: - return [f"result_0_4_0_{c['name']}" for c in _conf.compilers] + return [f"result_{c['name']}" for c in _conf.compilers] def ready_to_handle(_conf: Config, _res) -> bool: @@ -111,13 +120,39 @@ def reshape_data(_conf, _res): def is_valid(_conf, _res): fields = target_fields(_conf) for f in fields: + # contract is empty, regardless of inputs if len(_res[f][0]) == 0: return False - if "deploy_error" in _res[f][0]: - # TODO: deploy errors are supposed to be compared and handled as well - return False return True +def check_deploy_errors(_conf, _res): + deploy_errors = [] + fields = target_fields(_conf) + + has_error = False + # reshaping: init->[compilers] + for f in fields: + for j, depl in enumerate(_res[f]): + if j > len(deploy_errors) - 1: + deploy_errors.append([]) + deploy_errors[j].append(_res[f][j].get("deploy_error", None)) + if deploy_errors[j][-1] is not None: + has_error = True + + deploy_results = [] + for i, errors in enumerate(deploy_errors): + for j, error in enumerate(errors): + if j == len(errors) - 1: + break + verify_result = verify_and_catch(compilation_error_handler, + (errors[j], errors[j+1])) + deploy_results.append({ + "compilers": (fields[j], fields[j + 1]), + "deployment": i, + "results": verify_result + }) + return has_error, deploy_results + if __name__ == '__main__': conf = Config() @@ -137,7 +172,7 @@ def is_valid(_conf, _res): verification_results = [] for res in unhandled_results: - logger.debug(f"Handling result: {res['generation_id']}") + logger.info(f"Handling result: {res['generation_id']}") logger.debug(res) if not ready_to_handle(conf, res): logger.debug("%s is not ready yet", res["generation_id"]) @@ -145,6 +180,12 @@ def is_valid(_conf, _res): if not is_valid(conf, res): continue + + has_errors, results = check_deploy_errors(conf, res) + if has_errors: + verification_results.append({"generation_id": res["generation_id"], "results": results}) + continue + reshaped_res = reshape_data(conf, res) _r = verify_results(conf, reshaped_res) verification_results.append({"generation_id": res["generation_id"], "results": _r}) diff --git a/vyperProtoNewRawCallBug.proto b/vyperProtoNewRawCallBug.proto new file mode 100644 index 0000000..9dbfe17 --- /dev/null +++ b/vyperProtoNewRawCallBug.proto @@ -0,0 +1,828 @@ +syntax = "proto3"; + +message Int { + uint32 n = 1; + bool sign = 2; +} + +message Bool {} + +message Decimal {} + +message BytesM { + uint32 m = 1; +} + +message String { + uint32 max_len = 1; +} + +message Address {} + +message ByteArray { + uint32 max_len = 1; +} + +message VarRef { + oneof type { + Bool b = 2; + //Decimal d = 3; + BytesM bM = 4; + String s = 5; + Address adr = 6; + ByteArray barr = 7; + FixedList list = 9; + DynArray dyn = 10; + } + Int i = 1; + uint32 varnum = 8; +} + +message BoolBinOp { + enum BOp { + AND = 0; + OR = 1; + EQ = 2; + INEQ = 3; + } + BOp op = 1; + BoolExpression left = 2; + BoolExpression right = 3; +} + +message IntBoolBinOp { + enum BOp { + EQ = 0; + INEQ = 1; + LESS = 2; + LESSEQ = 3; + GREATER = 4; + GREATEREQ = 5; + } + BOp op = 1; + IntExpression left = 2; + IntExpression right = 3; +} + +message DecimalBoolBinOp { + enum BOp { + EQ = 0; + INEQ = 1; + LESS = 2; + LESSEQ = 3; + GREATER = 4; + GREATEREQ = 5; + } + BOp op = 1; + DecimalExpression left = 2; + DecimalExpression right = 3; +} + +message BoolUnOp { + BoolExpression expr = 1; +} + +message BoolExpression { + oneof expr { + BoolBinOp boolBinOp = 1; + BoolUnOp boolUnOp = 2; + IntBoolBinOp intBoolBinOp = 3; + //DecimalBoolBinOp decBoolBinOp = 4; + VarRef varRef = 6; + RawCall raw_call = 7; + ConvertFromInt convert_int = 8; + //DecimalExpression convert_decimal = 9; + AddressExpression convert_address = 10; + ConvertFromBytesM convert_bytesm = 11; + BytesExpression convert_bytes = 12; + StringExpression convert_string = 13; + // Convert convert = 7; + } + Literal lit = 5; +} + +message AddressExpression { + oneof expr { + //CreateMinimalProxy cmp = 1; + //CreateFromBlueprint cfb = 2; + VarRef varRef = 4; + //CreateCopyOf cco = 5; + //EcRecover ecRec = 6; + ConvertFromInt convert_int = 7; + ConvertFromBytesM convert_bytesm = 8; + BytesExpression convert_bytes = 9; + // Convert convert = 5; + } + Literal lit = 3; +} + +message IntBinOp { + enum BOp { + ADD = 0; + SUB = 1; + MUL = 2; + DIV = 3; + MOD = 4; + EXP = 5; + BIT_AND = 6; + BIT_OR = 7; + BIT_XOR = 8; + LEFT_SHIFT = 9; + RIGHT_SHIFT = 10; + } + + BOp op = 1; + IntExpression left = 2; + IntExpression right = 3; +} + +message IntUnOp { + IntExpression expr = 1; +} + +message DecimalBinOp { + enum BOp { + ADD = 0; + SUB = 1; + MUL = 2; + DIV = 3; + MOD = 4; + } + + BOp op = 1; + DecimalExpression left = 2; + DecimalExpression right = 3; +} + +message DecimalUnOp { + DecimalExpression expr = 1; +} + +// No enums yet +// Enums can be converted to and from uint256 only. +message IntExpression { + Literal lit = 1; + oneof expr { + IntBinOp binOp = 2; + IntUnOp unOp = 3; + VarRef varRef = 4; + ConvertFromInt convert_int = 5; + //DecimalExpression convert_decimal = 6; + BoolExpression convert_bool = 7; + AddressExpression convert_address = 8; + ConvertFromBytesM convert_bytesm = 9; + BytesExpression convert_bytes = 10; + } +} + +message ConvertFromInt { + IntExpression exp = 1; + Int i = 2; +} + +message ConvertFromBytesM { + BytesMExpression exp = 1; + BytesM bM = 2; +} + + +message BytesMExpression { + Literal lit = 3; + oneof expr { + Sha256 sha = 1; + VarRef varRef = 2; + Keccak256 keccak = 4; + ConvertFromInt convert_int = 5; + //DecimalExpression convert_decimal = 6; + BoolExpression convert_bool = 7; + AddressExpression convert_address = 8; + ConvertFromBytesM convert_bytesm = 9; + BytesExpression convert_bytes = 10; + // Convert convert = 5; + } +} + +message BytesExpression { + oneof expr { + VarRef varRef = 1; + RawCall raw_call = 2; + // Convert convert = 2; + ConcatBytes concat = 4; + StringExpression convert_string = 5; + } + Literal lit = 3; +} + +message StringExpression { + oneof expr { + VarRef varRef = 1; + // Convert convert = 2; + ConcatString concat = 2; + BytesExpression convert_bytes = 4; + } + Literal lit = 3; +} + +message DecimalExpression { + oneof expr { + DecimalBinOp binOp = 1; + DecimalUnOp unOp = 2; + VarRef varRef = 4; + ConvertFromInt convert_int = 5; + BoolExpression convert_bool = 6; + ConvertFromBytesM convert_bytesm = 7; + BytesExpression convert_bytes = 8; + // Convert convert = 5; + } + Literal lit = 3; +} + + +message TypedExpression { + AddressExpression addrExp = 1; + BoolExpression boolExp = 2; + BytesMExpression bmExp = 3; + BytesExpression bExp = 4; + StringExpression strExp = 5; + //DecimalExpression decExpression = 6; + IntExpression intExp = 7; + FixedListAddress addrList = 9; + FixedListBool boolList = 10; + FixedListBytesM bmList = 11; + FixedListInt intList = 12; + //FixedListDecimal decList = 13; + DynArrayAddress addrDyn = 14; + DynArrayBool boolDyn = 15; + DynArrayBytesM bmDyn = 16; + DynArrayInt intDyn = 17; + //DynArrayDecimal decDyn = 18; + DynArrayString strDyn = 19; + DynArrayByteArray bytesDyn = 20; + DynArrayListAddress ladrDyn = 21; + //DynArrayListDecimal ldecDyn = 22; + DynArrayListBool lboolByn = 23; + DynArrayListBytesM lbmDyn = 24; + DynArrayListInt lintDyn = 25; +} + + + +// must have atleast one member +message FixedListAddress{ + oneof other { + VarRef varRef = 3; + } + AddressExpression rexp = 1; + repeated AddressExpression exp = 2; +} + +message FixedListBool{ + oneof other { + VarRef varRef = 3; + } + BoolExpression rexp = 1; + repeated BoolExpression exp = 2; +} + +message FixedListBytesM{ + oneof other { + VarRef varRef = 3; + } + BytesMExpression rexp = 1; + repeated BytesMExpression exp = 2; +} + +message FixedListInt{ + oneof other { + VarRef varRef = 3; + EcAdd ecadd = 4; + EcMul ecmul = 5; + } + IntExpression rexp = 1; + repeated IntExpression exp = 2; +} + +message FixedListDecimal{ + oneof other { + VarRef varRef = 3; + } + DecimalExpression rexp = 1; + repeated DecimalExpression exp = 2; +} + +message DynArrayAddress{ + oneof other { + VarRef varRef = 3; + } + AddressExpression rexp = 1; + repeated AddressExpression exp = 2; +} + +message DynArrayBool{ + oneof other { + VarRef varRef = 3; + } + BoolExpression rexp = 1; + repeated BoolExpression exp = 2; +} + +message DynArrayBytesM{ + oneof other { + VarRef varRef = 3; + } + BytesMExpression rexp = 1; + repeated BytesMExpression exp = 2; +} + +message DynArrayInt{ + oneof other { + VarRef varRef = 3; + } + IntExpression rexp = 1; + repeated IntExpression exp = 2; +} + +message DynArrayDecimal{ + oneof other { + VarRef varRef = 3; + } + DecimalExpression rexp = 1; + repeated DecimalExpression exp = 2; +} + +message DynArrayString{ + oneof other { + VarRef varRef = 3; + } + StringExpression rexp = 1; + repeated StringExpression exp = 2; +} + +message DynArrayByteArray{ + oneof other { + VarRef varRef = 3; + } + BytesExpression rexp = 1; + repeated BytesExpression exp = 2; +} + +message DynArrayListAddress{ + oneof other { + VarRef varRef = 3; + } + FixedListAddress rexp = 1; + repeated FixedListAddress exp = 2; +} + +message DynArrayListDecimal{ + oneof other { + VarRef varRef = 3; + } + FixedListDecimal rexp = 1; + repeated FixedListDecimal exp = 2; +} + +message DynArrayListBool{ + oneof other { + VarRef varRef = 3; + } + FixedListBool rexp = 1; + repeated FixedListBool exp = 2; +} + +message DynArrayListBytesM{ + oneof other { + VarRef varRef = 3; + } + FixedListBytesM rexp = 1; + repeated FixedListBytesM exp = 2; +} + +message DynArrayListInt{ + oneof other { + VarRef varRef = 3; + } + FixedListInt rexp = 1; + repeated FixedListInt exp = 2; +} + +message Literal { + bool boolval = 2; + //uint64 decimalval = 3; // TO-DO: make this as int64 to enable signed variables + bytes bMval = 4; + string strval = 5; + uint64 addval = 6; + uint64 barrval = 7; + uint64 intval = 1; // check if we can make it just int +} + +//message BinaryOp { +// enum BOp { +// ADD = 0; +// SUB = 1; +// MUL = 2; +// DIV = 3; +// MOD = 4; +// EXP = 5; +// AND = 6; +// OR = 7; +// EQ = 8; +// INEQ = 9; +// LESS = 10; +// LESSEQ = 11; +// GREATER = 12; +// GREATEREQ = 13; +// BIT_AND = 14; +// BIT_OR = 15; +// BIT_XOR = 16; +// LEFT_SHIFT = 17; +// RIGHT_SHIFT = 18; +// } +// +// BOp op = 1; +// Expression left = 2; +// Expression right = 3; +//} +// +//message UnaryOp { +// enum UOp { +// NOT = 0; +// MINUS = 1; +// BIT_NOT = 2; +// BALANCE = 3; +// CODEHASH = 4; +// CODESIZE = 5; +// IS_CONTRACT = 6; +// CODE = 7; +// } +// +// UOp op = 1; +// Expression expr = 2; +//} + +//message Expression { +// oneof expr_oneof { +// Literal cons = 2; +// BinaryOp binop = 3; +// UnaryOp unop = 4; +// // NullaryOp nop = 5; +// CreateMinimalProxy cr_min_proxy = 5; +// CreateFromBlueprint cr_bp = 6; +// Sha256 sha = 7; +// } +// VarRef varref = 1; +//} + +message IfStmtCase { + BoolExpression cond = 1; + Block if_body = 2; +} + +message IfStmt { + repeated IfStmtCase cases = 1; + optional Block else_case = 2; +} + +message ForStmtRanged { + int32 start = 1; + int32 stop = 2; +} + +// imo should be expression, but there are restrictions +// ref_id for range(x, x + N) +message ForStmtVariable { + optional VarRef ref_id = 1; + uint32 length = 2; +} + +message ForStmt { + oneof for_oneof { + ForStmtVariable variable = 2; + } + ForStmtRanged ranged = 1; + Block body = 3; +} + +message VarDecl { + enum Mutability { + REGULAR = 0; + CONSTANT = 1; + IMMUTABLE = 2; + } + + oneof type { + Bool b = 2; + //Decimal d = 3; + BytesM bM = 4; + String s = 5; + Address adr = 6; + ByteArray barr = 7; + FixedList list = 10; + DynArray dyn = 11; + } + Int i = 1; + TypedExpression expr = 8; + Mutability mut = 9; +} + +message AssignmentStatement { + VarRef ref_id = 1; + TypedExpression expr = 2; +} + +message FuncCall { + uint32 func_num = 1; + ReturnPayload params = 2; +} + +// probably add builtins to expression too +message Statement { + oneof stmt_oneof { + VarDecl decl = 1; + //ForStmt for_stmt = 3; + //IfStmt if_stmt = 4; + //FuncCall func_call = 7; + //ContinueStatement cont_stmt = 8; + //BreakStatement break_stmt = 9; + //AssertStatement assert_stmt = 10; + //AppendArray append_stmt = 11; + //PopArray pop_stmt = 12; + //SendStatement send_stmt = 13; + RawCall raw_call = 14; + //RawLog raw_log = 15; + } + AssignmentStatement assignment = 2; +} + +message RawLog { + FixedListBytesM topics = 1; + uint32 topic_amount = 2; + + oneof data { + BytesExpression data_bs = 3; + } + BytesMExpression data_bm = 4; +} + +message Block { + repeated Statement statements = 1; + ExitStatement exit_d = 2; +} + +message Reentrancy { + string key = 1; +} + +message FixedList{ + oneof type { + Bool b = 2; + //Decimal d = 3; + BytesM bM = 4; + Address adr = 5; + } + Int i = 1; + uint32 n = 6; +} + +// ENUM aswell +message DynArray{ + oneof type { + Bool b = 2; + //Decimal d = 3; + BytesM bM = 4; + String s = 5; + Address adr = 6; + ByteArray barr = 7; + FixedList list = 9; + } + Int i = 1; + uint32 n = 10; +} + +message FuncParam { + oneof type { + Bool b = 2; + //Decimal d = 3; + BytesM bM = 4; + String s = 5; + Address adr = 6; + ByteArray barr = 7; + FixedList list = 8; + DynArray dyn = 9; + } + Int i = 1; +} + +message Func { + enum Visibility { + EXTERNAL = 0; + INTERNAL = 1; + } + + enum Mutability { + PURE = 0; + VIEW = 1; + NONPAYABLE = 2; + PAYABLE = 3; + } + + Visibility vis = 1; + Mutability mut = 2; + optional Reentrancy ret = 3; + repeated FuncParam input_params = 4; + repeated FuncParam output_params = 5; + Block block = 6; +} + +message ContractInit { + enum Mutability { + NONPAYABLE = 0; + PAYABLE = 1; + } + + Mutability mut = 1; + repeated FuncParam input_params = 2; + Block block = 3; + bool flag = 4; +} + +message DefaultFunc { + enum Mutability { + PURE = 0; + VIEW = 1; + NONPAYABLE = 2; + PAYABLE = 3; + } + + Mutability mut = 2; + optional Reentrancy ret = 3; + repeated FuncParam output_params = 5; + Block block = 6; +} + +message Contract { + repeated VarDecl decls = 1; + repeated Func functions = 2; + ContractInit init = 3; + optional DefaultFunc def_func = 4; +} + +//message Convert { +// enum InputType { +// INT = 0; +// } +// InputType from_type = 1; +// TypedExpression value = 2; +//} + +message CreateMinimalProxy { + AddressExpression target = 1; + optional IntExpression value = 2; + optional BytesMExpression salt = 3; +} + +message CreateCopyOf { + AddressExpression target = 1; + optional IntExpression value = 2; + optional BytesMExpression salt = 3; +} + +// ecrecover(hash: bytes32, v: uint256 | uint8, r: uint256 | bytes32, s: uint256 | bytes32) +message EcRecover { + BytesMExpression hash = 1; + optional IntExpression v8 = 2; + IntExpression vi = 3; + optional BytesMExpression rb = 4; + IntExpression ri = 5; + optional BytesMExpression sb = 6; + IntExpression si = 7; +} + +message CreateFromBlueprint { + message RawArgs { + BytesExpression arg = 1; + Literal flag = 2; + } + AddressExpression target = 1; + // repeated Expression args = 2; // TODO: come up with the case where no matter amount and types of expressions + optional RawArgs rawArgs = 3; + optional IntExpression value = 4; + optional IntExpression code_offset = 5; + optional BytesMExpression salt = 6; +} + +message SendStatement { + AddressExpression to = 1; + IntExpression amount = 2; + optional IntExpression gas = 3; +} + +message Selfdestruct { + AddressExpression to = 1; +} + +message Sha256 { + oneof typed_value { + StringExpression strVal = 1; + BytesExpression bVal = 2; + } + BytesMExpression bmVal = 3; +} + +message Keccak256 { + oneof typed_value { + StringExpression strVal = 1; + BytesExpression bVal = 2; + } + BytesMExpression bmVal = 3; +} + +message ExitStatement { + bool flag = 1; + ReturnPayload payload = 2; + oneof exit_st { + Selfdestruct selfd = 3; + RaiseStatement raise_st = 4; + RawRevert raw_revert = 5; + } +} + +message RaiseStatement { + StringExpression errval = 1; +} + +message RawRevert { + BytesExpression data = 1; +} + +message ReturnPayload { + TypedExpression one = 1; + TypedExpression two = 2; + TypedExpression three = 3; + TypedExpression four = 4; + TypedExpression five = 5; +} + +message BreakStatement {} + +message ContinueStatement {} + +message AssertStatement { + BoolExpression cond = 1; + StringExpression reason = 2; +} + +message AppendArray { + VarRef varRef = 1; + TypedExpression expr = 2; +} + +message PopArray { + VarRef varRef = 1; +} + +message RawCall { + AddressExpression to = 1; + BytesExpression data = 2; + Literal max_out = 3; + optional IntExpression gas = 4; + optional IntExpression value = 5; + Literal delegate = 6; + Literal static = 7; + Literal revert = 8; +} + +message EcAdd { + FixedListInt x = 1; + FixedListInt y = 2; +} + +message EcMul { + FixedListInt point = 1; + IntExpression scalar = 2; +} + +message ConcatString { + StringTypeSize a = 1; + StringTypeSize b = 2; + repeated StringTypeSize c = 3; +} + +message StringTypeSize { + StringExpression s = 1; + uint32 s_size = 2; +} + +message ConcatBytes { + BytesTypesSize a = 1; + BytesTypesSize b = 2; + repeated BytesTypesSize c = 3; +} + +message BytesTypesSize { + oneof bytes { + BytesMExpression b_bm = 1; + } + BytesExpression b_bs = 2; + uint32 s_size = 3; +} \ No newline at end of file