1#include <gtest/gtest.h>
22 context.register_contract_from_bytecode(function);
24 std::cout <<
"Failed to register predefined function: " << function.size() <<
std::endl;
53 FF fee_required_da =
FF(
tx.effective_gas_fees.fee_per_da_gas) *
FF(
tx.gas_settings.gas_limits.da_gas);
54 FF fee_required_l2 =
FF(
tx.effective_gas_fees.fee_per_l2_gas) *
FF(
tx.gas_settings.gas_limits.l2_gas);
90 return result.
output.at(0);
98 auto set_instruction_1 =
102 auto set_instruction_2 =
108 auto return_options =
116 return result.
output.at(0);
132 auto result = get_result_of_instruction(add_instruction);
133 EXPECT_EQ(result, 7);
143 auto result = get_result_of_instruction(sub_instruction);
144 EXPECT_EQ(result, 3);
154 auto result = get_result_of_instruction(mul_instruction);
155 EXPECT_EQ(result, 10);
165 auto result = get_result_of_instruction(div_instruction);
166 EXPECT_EQ(result, 2);
177 EXPECT_EQ(result, 0);
188 EXPECT_EQ(result, 0);
199 EXPECT_EQ(result, 0);
209 auto result = get_result_of_instruction(and_instruction);
210 EXPECT_EQ(result, 0);
220 auto result = get_result_of_instruction(or_instruction);
221 EXPECT_EQ(result, 7);
231 auto result = get_result_of_instruction(xor_instruction);
232 EXPECT_EQ(result, 7);
242 auto result = get_result_of_instruction(shl_instruction);
243 EXPECT_EQ(result, 20);
253 auto result = get_result_of_instruction(shr_instruction);
254 EXPECT_EQ(result, 1);
265 auto set_instruction_1 =
269 auto set_instruction_2 =
275 auto return_options =
282 auto result = simulate_with_default_tx(
bytecode, {});
283 EXPECT_EQ(result.output.at(0), 2);
289 auto set_instruction =
298 auto return_options =
305 auto result = simulate_with_default_tx(
bytecode, {});
306 EXPECT_EQ(result.output.at(0), 255);
321 auto result = get_result_of_instruction_16(add_instruction);
322 EXPECT_EQ(result, 7);
332 auto result = get_result_of_instruction_16(sub_instruction);
333 EXPECT_EQ(result, 3);
343 auto result = get_result_of_instruction_16(mul_instruction);
344 EXPECT_EQ(result, 10);
354 auto result = get_result_of_instruction_16(div_instruction);
355 EXPECT_EQ(result, 2);
366 EXPECT_EQ(result, 0);
377 EXPECT_EQ(result, 0);
388 EXPECT_EQ(result, 0);
398 auto result = get_result_of_instruction_16(and_instruction);
399 EXPECT_EQ(result, 0);
409 auto result = get_result_of_instruction_16(or_instruction);
410 EXPECT_EQ(result, 7);
420 auto result = get_result_of_instruction_16(xor_instruction);
421 EXPECT_EQ(result, 7);
431 auto result = get_result_of_instruction_16(shl_instruction);
432 EXPECT_EQ(result, 20);
442 auto result = get_result_of_instruction_16(shr_instruction);
443 EXPECT_EQ(result, 1);
454 auto set_instruction_1 =
458 auto set_instruction_2 =
464 auto return_options =
471 auto result = simulate_with_default_tx(
bytecode, {});
472 EXPECT_EQ(result.output.at(0), 2);
478 auto set_instruction =
487 auto return_options =
494 auto result = simulate_with_default_tx(
bytecode, {});
495 EXPECT_EQ(result.output.at(0), 255);
518 auto return_options =
525 auto result = simulate_with_default_tx(
bytecode, {});
526 EXPECT_EQ(result.output.at(0), 2);
546 auto return_options =
553 auto result = simulate_with_default_tx(
bytecode, {});
554 EXPECT_EQ(result.output.at(0), 2);
562 const uint16_t test_value = 0xABCD;
563 auto set_instruction =
566 .value = test_value };
568 auto return_options =
575 auto result = simulate_with_default_tx(
bytecode, {});
576 EXPECT_EQ(result.output.at(0), test_value);
581 const uint32_t test_value = 0x12345678UL;
582 auto set_instruction =
585 .value = test_value };
587 auto return_options =
594 auto result = simulate_with_default_tx(
bytecode, {});
595 EXPECT_EQ(result.output.at(0), test_value);
601 const uint64_t test_value = 0xABCDEF0123456789ULL;
602 auto set_instruction =
605 .value = test_value };
607 auto return_options =
614 auto result = simulate_with_default_tx(
bytecode, {});
615 EXPECT_EQ(result.output.at(0), test_value);
621 const uint64_t test_value_low = 0xFEDCBA9876543210ULL;
622 const uint64_t test_value_high = 0x123456789ABCDEF0ULL;
624 (
static_cast<uint128_t>(test_value_high) << 64) |
static_cast<uint128_t>(test_value_low);
625 auto set_instruction =
628 .value_low = test_value_low,
629 .value_high = test_value_high };
633 .return_value_offset_index = 0 };
639 auto result = simulate_with_default_tx(
bytecode, {});
640 EXPECT_EQ(result.output.at(0), test_value);
647 auto set_instruction =
650 .value = test_value };
652 auto return_options =
659 auto result = simulate_with_default_tx(
bytecode, {});
660 EXPECT_EQ(result.output.at(0), test_value);
666 const uint8_t test_value = 0x42;
667 const uint8_t test_value2 = 0x43;
668 auto set_instruction =
671 .value = test_value };
674 .value = test_value2 };
680 auto return_options =
687 auto result = simulate_with_default_tx(
bytecode, {});
688 EXPECT_EQ(result.output.at(0), test_value);
694 const uint16_t test_value = 0xbabe;
695 const uint16_t test_value2 = 0xc0fe;
696 auto set_instruction =
699 .value = test_value };
700 auto set_instruction2 =
703 .value = test_value2 };
709 auto return_options =
716 auto result = simulate_with_default_tx(
bytecode, {});
717 EXPECT_EQ(result.output.at(0), test_value);
735 .value = first_boolean_value };
739 .value = second_boolean_value };
742 for (uint8_t i = 2; i < 5; i++) {
743 auto set_instruction =
747 instruction_blocks.push_back({ set_instruction });
751 .return_value_offset_index = 1 };
756 .else_program_block_instruction_block_idx = 4,
757 .condition_offset_index = 0 });
759 .else_program_block_instruction_block_idx = 3,
760 .condition_offset_index = 1 });
764 return result.
output.at(0);
772 auto set_instruction_block_1 =
775 .value = condition_value };
781 auto instruction_blocks =
785 .return_value_offset_index = 1 };
790 .else_program_block_instruction_block_idx = 2,
791 .condition_offset_index = 0 });
796 return result.
output.at(0);
814 auto return_options =
821 auto result = simulate_with_default_tx(
bytecode, {});
822 EXPECT_EQ(result.output.at(0), 11);
844 auto instruction_blocks =
846 auto return_options =
854 auto result = simulate_with_default_tx(
bytecode, {});
855 EXPECT_EQ(result.output.at(0), 12);
870 auto return_options =
877 auto result = simulate_with_default_tx(
bytecode, {});
878 EXPECT_EQ(result.output.at(0), 10);
903 set_true_block, set_false_block, block2_instructions, block3_instructions
905 auto return_options =
911 .else_program_block_instruction_block_idx = 3,
912 .condition_offset_index = 1 });
913 auto bytecode_1 =
control_flow.build_bytecode(return_options);
914 auto control_flow2 =
ControlFlow(instruction_blocks);
918 .else_program_block_instruction_block_idx = 3,
919 .condition_offset_index = 1 });
920 auto bytecode_2 = control_flow2.build_bytecode(return_options);
922 auto result_1 = simulate_with_default_tx(bytecode_1, {});
923 auto result_2 = simulate_with_default_tx(bytecode_2, {});
924 EXPECT_EQ(result_1.output.at(0), 11);
925 EXPECT_EQ(result_2.output.at(0), 12);
930 EXPECT_EQ(simulate_jump_if_depth_2_helper(1, 1), 2);
931 EXPECT_EQ(simulate_jump_if_depth_2_helper(1, 0), 3);
932 EXPECT_EQ(simulate_jump_if_depth_2_helper(0, 1), 4);
933 EXPECT_EQ(simulate_jump_if_depth_2_helper(0, 0), 4);
938 EXPECT_EQ(simulate_jump_to_block_helper(1), 2);
939 EXPECT_EQ(simulate_jump_to_block_helper(0), 2);
960 .value = ff_value } };
963 const uint64_t u128_value_low = 0xFEDCBA9876543210ULL;
964 const uint64_t u128_value_high = 0x123456789ABCDEF0ULL;
968 .value_low = u128_value_low,
969 .value_high = u128_value_high } };
971 auto instruction_blocks =
981 .else_program_block_instruction_block_idx = 2,
982 .condition_offset_index = 0 });
995 auto control_flow_true =
ControlFlow(instruction_blocks);
998 .else_program_block_instruction_block_idx = 2,
999 .condition_offset_index = 0 });
1007 auto bytecode_true = control_flow_true.build_bytecode(
ReturnOptions{
1010 auto result_true = simulate_with_default_tx(bytecode_true, {});
1011 EXPECT_EQ(result_true.output.at(0), ff_value);
1018 auto instruction_blocks_false =
1021 auto control_flow_false =
ControlFlow(instruction_blocks_false);
1024 .else_program_block_instruction_block_idx = 2,
1025 .condition_offset_index = 0 });
1034 (
static_cast<uint128_t>(u128_value_high) << 64) |
static_cast<uint128_t>(u128_value_low);
1035 auto bytecode_false = control_flow_false.build_bytecode(
ReturnOptions{
1038 auto result_false = simulate_with_default_tx(bytecode_false, {});
1039 EXPECT_EQ(result_false.output.at(0), expected_u128_value);
1047 auto set_value_instruction =
1058 auto sload_instruction =
1063 auto set_value_instruction2 =
1069 set_value_instruction, sstore_instruction, sload_instruction, set_value_instruction2
1076 .return_value_offset_index = 1 };
1081 auto result = simulate_with_default_tx(
bytecode, {});
1082 EXPECT_EQ(result.output.at(0), 10);
1092 auto getenvvar_instruction =
1098 auto return_options =
1103 return result.
output.at(0);
1109 EXPECT_EQ(getenvvar_helper(0),
1110 FF(
"0x02fea672ef18fe4b8d13dcfd8943797c99b9885da7b338d224dd5136a0cc8a6f"));
1113 EXPECT_EQ(getenvvar_helper(3),
CHAIN_ID);
1114 EXPECT_EQ(getenvvar_helper(4),
VERSION);
1119 EXPECT_EQ(getenvvar_helper(9), 0);
1128 auto set_field_instruction =
1141 { set_field_instruction, emit_nullifier_instruction, nullifier_exists_instruction }
1147 auto result = simulate_with_default_tx(
bytecode, {});
1148 EXPECT_EQ(result.output.at(0), 1);
1153 auto set_field_instruction =
1166 { set_field_instruction, emit_nullifier_instruction, nullifier_exists_instruction }
1172 auto result = simulate_with_default_tx(
bytecode, {});
1173 EXPECT_EQ(result.output.at(0), 0);
1178 auto emit_note_hash_instruction =
1181 auto note_hash_exists_instruction =
1186 auto instruction_blocks =
1192 auto result = simulate_with_default_tx(
bytecode, {});
1193 EXPECT_FALSE(result.reverted);
1217 auto result = simulate_with_default_tx(
bytecode, {
FF(1337) });
1218 EXPECT_EQ(result.output.at(0), 1337);
1224 auto set_field_instruction =
1228 auto set_field_instruction2 =
1233 auto instruction_blocks =
1237 control_flow.process_cfg_instruction(internal_call_instruction);
1240 auto result = simulate_with_default_tx(
bytecode, {});
1241 EXPECT_EQ(result.output.at(0), 313373);
1250 auto set_field_instruction =
1254 auto set_boolean_instruction =
1259 auto instruction_blocks =
1263 control_flow.process_cfg_instruction(internal_call_instruction);
1271 auto result = simulate_with_default_tx(
bytecode, {});
1272 EXPECT_EQ(result.output.at(0), 1337);
1280 auto set_field_instruction =
1284 auto set_field_instruction2 =
1288 auto set_field_instruction3 =
1295 { set_field_instruction, set_field_instruction2, set_field_instruction3 }
1299 control_flow.process_cfg_instruction(internal_call_instruction);
1300 control_flow.process_cfg_instruction(internal_call_instruction2);
1303 auto result = simulate_with_default_tx(
bytecode, {});
1304 EXPECT_EQ(result.output.at(0), 313373);
1326 auto set_field_instruction0 =
1330 auto set_field_instruction1 =
1334 auto set_field_instruction2 =
1338 auto set_field_instruction3 =
1346 { set_field_instruction0, set_field_instruction1, set_field_instruction2, set_field_instruction3 }
1351 control_flow.process_cfg_instruction(internal_call_instruction);
1353 control_flow.process_cfg_instruction(internal_call_instruction2);
1365 control_flow.process_cfg_instruction(internal_call_instruction3);
1372 auto result = simulate_with_default_tx(
bytecode, {});
1373 EXPECT_EQ(result.output.at(0), 313373);
1380 auto set_field_instruction =
1384 auto set_field_instruction2 =
1391 .pointer_address_seed = 100,
1396 auto instruction_blocks =
1402 auto result = simulate_with_default_tx(
bytecode, {});
1403 EXPECT_EQ(result.output.at(0), 30);
1408 auto set_field_instruction =
1412 auto set_field_instruction2 =
1419 .pointer_address_seed = 100,
1420 .base_offset_seed = 100,
1425 auto instruction_blocks =
1431 auto result = simulate_with_default_tx(
bytecode, {});
1432 EXPECT_EQ(result.output.at(0), 30);
1437 auto set_field_instruction =
1451 auto instruction_blocks =
1457 auto result = simulate_with_default_tx(
bytecode, {});
1458 EXPECT_EQ(result.output.at(0), 400);
1463 auto set_field_instruction =
1469 .pointer_address_seed = 100,
1476 .pointer_address_seed = 200,
1480 auto instruction_blocks =
1486 auto result = simulate_with_default_tx(
bytecode, {});
1487 EXPECT_EQ(result.output.at(0), 200);
1495 auto sendl2tol1msg_instruction =
1505 auto result = simulate_with_default_tx(
bytecode, {});
1506 EXPECT_EQ(result.reverted,
false);
1513 uint32_t log_size = 1;
1532 auto result = simulate_with_default_tx(
bytecode, {});
1533 EXPECT_EQ(result.reverted,
false);
1545 instructions.push_back(
1560 return result.
output.at(0);
1576 instructions.push_back(
1581 instructions.push_back(
1584 uint16_t arg_size = 0;
1591 .calldata_address = args_address,
1592 .calldata_size_address = arg_size_address,
1593 .calldata_size = arg_size,
1594 .is_static_call =
false });
1597 .
copy_size_offset = 6, .dst_address = 7, .rd_start = 0, .rd_start_offset = 8 });
1604 auto result = simulate_with_default_tx(
bytecode, {});
1605 EXPECT_EQ(result.output.at(0), 2);
1611 EXPECT_EQ(get_contract_instance_helper(0),
1612 FF(
"0x0000000000000000000000000000000000000000000000000000000000000064"));
1613 EXPECT_EQ(get_contract_instance_helper(1),
1614 FF(
"0x0dc97dd1cc90c276ca76f34abb5085e1ae3addd8ace763a5da908bacf147d972"));
1615 EXPECT_EQ(get_contract_instance_helper(2),
1616 FF(
"0x0000000000000000000000000000000000000000000000000000000000000000"));
1631 instructions.push_back(
1636 instructions.push_back(
1639 uint16_t arg_size = 0;
1646 .calldata_address = args_address,
1647 .calldata_size_address = arg_size_address,
1648 .calldata_size = arg_size,
1649 .is_static_call =
false });
1651 instructions.push_back(
1659 auto result = simulate_with_default_tx(
bytecode, {});
1660 EXPECT_EQ(result.output.at(0),
FF::one());
1675 instructions.push_back(
1680 instructions.push_back(
1683 uint16_t arg_size = 0;
1690 .calldata_address = args_address,
1691 .calldata_size_address = arg_size_address,
1692 .calldata_size = arg_size,
1693 .is_static_call =
true });
1694 instructions.push_back(
1701 auto result = simulate_with_default_tx(
bytecode, {});
1702 EXPECT_EQ(result.output.at(0),
FF::zero());
1703 EXPECT_EQ(result.reverted,
false);
1717 instructions.push_back(
1722 instructions.push_back(
1725 uint16_t arg_size = 0;
1732 .calldata_address = args_address,
1733 .calldata_size_address = arg_size_address,
1734 .calldata_size = arg_size,
1735 .is_static_call =
true });
1736 instructions.push_back(
1743 auto result = simulate_with_default_tx(
bytecode, {});
1744 EXPECT_EQ(result.output.at(0),
FF::zero());
1745 EXPECT_EQ(result.reverted,
false);
::FuzzInstruction FuzzInstruction
const uint32_t BLOCK_NUMBER
const std::vector< std::vector< uint8_t > > PREDEFINED_FUNCTIONS
constexpr uint128_t FEE_PER_DA_GAS
const bool IS_STATIC_CALL
constexpr uint128_t FEE_PER_L2_GAS
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
StrictMock< MockContractDB > contract_db
uses barretenberg/vm2 to simulate the bytecode
SimulatorResult simulate_with_default_tx(std::vector< uint8_t > &bytecode, std::vector< FF > calldata)
FF get_result_of_instruction_16(FuzzInstruction instruction, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::U8)
FF get_result_of_instruction(FuzzInstruction instruction, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::U8)
static FuzzerWorldStateManager * getInstance()
world_state::WorldStateRevision fork()
void write_fee_payer_balance(const AztecAddress &fee_payer, const FF &balance)
FF simulate_jump_if_depth_2_helper(uint8_t first_boolean_value, uint8_t second_boolean_value)
FF simulate_jump_to_block_helper(uint8_t condition_value)
FF getenvvar_helper(uint8_t type, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::FF)
FF get_contract_instance_helper(uint8_t member_enum, bb::avm2::MemoryTag return_value_tag=bb::avm2::MemoryTag::FF)
@ contract_address_address
AztecAddress contract_address
FuzzerWorldStateManager * ws_mgr
void register_functions(FuzzerContext &context)
TEST_F(ArithmeticFuzzTest, ADD8)
TEST_F(FuzzTest, DirectWithIndirect)
TEST_F(FuzzTest, CopyCalldataThenReturnData)
TEST_F(ControlFlowFuzzTest, JumpToNewBlockSmoke)
TEST_F(ExecutionEnvironmentFuzzTest, GetEnvVarSmoke)
TEST_F(ExternalCallsFuzzTest, ExternalCallToAdd8)
TEST_F(FuzzTest, InternalCalledBlockUsesInternalReturn)
TEST_F(FuzzTest, SendL2ToL1Msg)
TEST_F(FuzzTest, EmitNullifierThenNullifierExists)
TEST_F(FuzzTest, SstoreThenSload)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
unsigned __int128 uint128_t
Tx create_default_tx(const AztecAddress &contract_address, const AztecAddress &sender_address, const std::vector< FF > &calldata, const FF &transaction_fee, bool is_static_call, const Gas &gas_limit)
mem[result_offset] = mem[a_address] + mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] + mem[b_address]
mem[result_offset] = mem[a_address] & mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] & mem[b_address]
CALLDATACOPY: M[dstOffset:dstOffset+M[copySizeOffset]] = calldata[M[cdStartOffset]:M[cdStartOffset]+M...
CAST_16: cast mem[src_offset_index] to target_tag and store at dst_offset.
CAST_8: cast mem[src_offset_index] to target_tag and store at dst_offset.
mem[result_offset] = mem[a_address] / mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] / mem[b_address]
EMITNOTEHASH: M[note_hash_offset] = note_hash; emit note hash to the note hash tree.
AddressRef note_hash_address
EMITNULIFIER: inserts new nullifier to the nullifier tree.
ParamRef nullifier_address
ParamRef log_size_address
mem[result_offset] = mem[a_address] == mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] == mem[b_address]
finalizes the current block with Return and switches to the first non-terminated block
ReturnOptions return_options
ParamRef contract_address_address
GETENVVAR: M[result_offset] = getenvvar(type)
AddressRef result_address
inserts INTERNALCALL instruction to the current block creates a new block and sets it as the current ...
uint16_t target_program_block_instruction_block_idx
insert instruction block to the current block
uint16_t instruction_block_idx
finalizes the current block with jump if, creates two new blocks, sets the first as the then block an...
uint16_t then_program_block_instruction_block_idx
finalizes the current block with a jump to the block, which does not create a loop in the graph (defi...
uint16_t target_block_idx
finalizes the current block with jump, creates a new block and sets it as the current block
uint16_t target_program_block_instruction_block_idx
mem[result_offset] = mem[a_address] < mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] < mem[b_address]
mem[result_offset] = mem[a_address] <= mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] <= mem[b_address]
MOV_16 instruction: mem[dst_offset] = mem[src_offset].
MOV_8 instruction: mem[dst_offset] = mem[src_offset].
mem[result_offset] = mem[a_address] * mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] * mem[b_address]
NOTEHASHEXISTS: M[result_offset] = NOTEHASHEXISTS(M[notehash_offset], M[leaf_index_offset]) len = len...
NULLIFIEREXISTS: checks if nullifier exists in the nullifier tree Gets contract's address by GETENVVA...
ParamRef nullifier_address
mem[result_offset] = mem[a_address] | mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] | mem[b_address]
: RETURNDATASIZE + RETURNDATACOPY:
uint16_t copy_size_offset
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
MemoryTagWrapper value_tag
mem[result_offset] = mem[a_address] << mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] << mem[b_address]
mem[result_offset] = mem[a_address] >> mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] >> mem[b_address]
SLOAD: M[slot_offset] = slot; M[result_offset] = S[M[slotOffset]].
SSTORE: M[slot_offset_index] = slot; S[M[slotOffset]] = M[srcOffset].
mem[result_offset] = mem[a_address] - mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] - mem[b_address]
mem[result_offset] = mem[a_address] ^ mem[b_address] (16-bit)
mem[result_offset] = mem[a_address] ^ mem[b_address]
static constexpr field one()
static constexpr field zero()